rsnext/test/lib/wd-chain.js
Jan Potoms 3ffef60280
Fix webdriver error handling (#15491)
errors in script execution will result in timeout instead of failure. This PR makes sure to pass all arguments to `.then` so error handling is correctly set up. (`.then` needs to be able to take a second argument). I also removed `.finally`.

I don't know why, but it looks like the following test does something that prevents the tests after it from opening a new browser window on azure. I'm giving up, I shuffled the tests to put this one last.
```js
    it('shows warning when dynamic route mismatch is used on Link', async () => {
      await showsError(
        '/dynamic-route-mismatch',
        /Mismatching `as` and `href` failed to manually provide the params: post in the `href`'s `query`/,
        true,
        true
      )
    })
```
2020-07-29 10:30:06 +00:00

135 lines
2.9 KiB
JavaScript

import { until, By } from 'selenium-webdriver'
export default class Chain {
constructor(browser) {
this.browser = browser
}
updateChain(nextCall) {
if (!this.promise) {
this.promise = Promise.resolve()
}
this.promise = this.promise.then(nextCall)
this.then = (...args) => this.promise.then(...args)
this.catch = (...args) => this.promise.catch(...args)
return this
}
elementByCss(sel) {
return this.updateChain(() =>
this.browser.findElement(By.css(sel)).then((el) => {
el.sel = sel
el.text = () => el.getText()
el.getComputedCss = (prop) => el.getCssValue(prop)
el.type = (text) => el.sendKeys(text)
el.getValue = () =>
this.browser.executeScript(
`return document.querySelector('${sel}').value`
)
return el
})
)
}
elementById(sel) {
return this.elementByCss(`#${sel}`)
}
getValue() {
return this.updateChain((el) =>
this.browser.executeScript(
`return document.querySelector('${el.sel}').value`
)
)
}
text() {
return this.updateChain((el) => el.getText())
}
type(text) {
return this.updateChain((el) => el.sendKeys(text))
}
moveTo() {
return this.updateChain((el) => {
return this.browser
.actions()
.move({ origin: el })
.perform()
.then(() => el)
})
}
getComputedCss(prop) {
return this.updateChain((el) => {
return el.getCssValue(prop)
})
}
getAttribute(attr) {
return this.updateChain((el) => el.getAttribute(attr))
}
hasElementByCssSelector(sel) {
return this.eval(`document.querySelector('${sel}')`)
}
click() {
return this.updateChain((el) => {
return el.click().then(() => el)
})
}
elementsByCss(sel) {
return this.updateChain(() => this.browser.findElements(By.css(sel)))
}
waitForElementByCss(sel, timeout) {
return this.updateChain(() =>
this.browser.wait(until.elementLocated(By.css(sel), timeout))
)
}
waitForCondition(condition) {
return this.updateChain(() =>
this.browser.wait(async (driver) => {
return driver.executeScript('return ' + condition).catch(() => false)
})
)
}
eval(snippet) {
if (typeof snippet === 'string' && !snippet.startsWith('return')) {
snippet = `return ${snippet}`
}
return this.updateChain(() => this.browser.executeScript(snippet))
}
log(type) {
return this.updateChain(() => this.browser.manage().logs().get(type))
}
url() {
return this.updateChain(() => this.browser.getCurrentUrl())
}
back() {
return this.updateChain(() => this.browser.navigate().back())
}
forward() {
return this.updateChain(() => this.browser.navigate().forward())
}
refresh() {
return this.updateChain(() => this.browser.navigate().refresh())
}
close() {
return this.updateChain(() => Promise.resolve())
}
quit() {
return this.close()
}
}