3ffef60280
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 ) }) ```
135 lines
2.9 KiB
JavaScript
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()
|
|
}
|
|
}
|