diff options
Diffstat (limited to 'e2e/lib')
-rw-r--r-- | e2e/lib/Console.ts | 25 | ||||
-rw-r--r-- | e2e/lib/FormOptionPage.ts | 64 | ||||
-rw-r--r-- | e2e/lib/JSONOptionPage.ts | 22 | ||||
-rw-r--r-- | e2e/lib/OptionPage.ts | 36 | ||||
-rw-r--r-- | e2e/lib/Page.ts | 93 |
5 files changed, 239 insertions, 1 deletions
diff --git a/e2e/lib/Console.ts b/e2e/lib/Console.ts index 37b0597..233bf48 100644 --- a/e2e/lib/Console.ts +++ b/e2e/lib/Console.ts @@ -1,4 +1,4 @@ -import { WebDriver, By } from 'selenium-webdriver'; +import { WebDriver, By, Key } from 'selenium-webdriver'; export type CompletionItem = { type: string; @@ -25,6 +25,21 @@ export class Console { }); } + async execCommand(command: string): Promise<void> { + let input = await this.webdriver.findElement(By.css('input.vimvixen-console-command-input')); + await input.sendKeys(command, Key.ENTER); + } + + async getErrorMessage(): Promise<string> { + let p = await this.webdriver.findElement(By.css('.vimvixen-console-error')); + return p.getText(); + } + + async inputKeys(...keys: string[]) { + let input = await this.webdriver.findElement(By.css('input')); + await input.sendKeys(...keys); + } + getCompletions(): Promise<CompletionItem[]> { return this.webdriver.executeScript(() => { let items = document.querySelectorAll('.vimvixen-console-completion > li'); @@ -46,4 +61,12 @@ export class Console { return objs; }); } + + async close(): Promise<void> { + let input = await this.webdriver.findElement(By.css('input')); + await input.sendKeys(Key.ESCAPE); + // TODO remove sleep + await new Promise(resolve => setTimeout(resolve, 100)); + await (this.webdriver.switchTo() as any).parentFrame(); + } } diff --git a/e2e/lib/FormOptionPage.ts b/e2e/lib/FormOptionPage.ts new file mode 100644 index 0000000..c8ff341 --- /dev/null +++ b/e2e/lib/FormOptionPage.ts @@ -0,0 +1,64 @@ +import { Lanthan } from 'lanthan'; +import { WebDriver, By } from 'selenium-webdriver'; + +export default class FormOptionPage { + private webdriver: WebDriver; + + constructor(lanthan: Lanthan) { + this.webdriver = lanthan.getWebDriver(); + } + + async setBlacklist(nth: number, value: string): Promise<void> { + let selector = '.form-blacklist-form .column-url'; + let inputs = await this.webdriver.findElements(By.css(selector)); + if (inputs.length <= nth) { + throw new RangeError('Index out of range to set a blacklist') + } + await inputs[nth].sendKeys(value); + await this.webdriver.executeScript(`document.querySelectorAll('${selector}')[${nth}].blur()`); + } + + async setSearchEngine(nth: number, name: string, url: string) { + let selector = '.form-search-form input.column-name'; + let inputs = await this.webdriver.findElements(By.css(selector)); + if (inputs.length <= nth) { + throw new RangeError('Index out of range to set a search engine') + } + await inputs[nth].sendKeys(name); + await this.webdriver.executeScript(`document.querySelectorAll('${selector}')[${nth}].blur()`); + + selector = '.form-search-form input.column-url'; + inputs = await this.webdriver.findElements(By.css(selector)); + if (inputs.length <= nth) { + throw new RangeError('Index out of range to set a search engine') + } + await inputs[nth].sendKeys(url); + await this.webdriver.executeScript(`document.querySelectorAll('${selector}')[${nth}].blur()`); + } + + async addBlacklist(): Promise<void> { + let button = await this.webdriver.findElement(By.css('.form-blacklist-form .ui-add-button')) + await button.click(); + } + + async removeBlackList(nth: number): Promise<void> { + let buttons = await this.webdriver.findElements(By.css('.form-blacklist-form .ui-delete-button')); + if (buttons.length <= nth) { + throw new RangeError('Index out of range to remove blacklist') + } + await buttons[nth].click() + } + + async addSearchEngine(): Promise<void> { + let button = await this.webdriver.findElement(By.css('.form-search-form .ui-add-button')) + await button.click(); + } + + async setDefaultSearchEngine(nth: number): Promise<void> { + let radios = await this.webdriver.findElements(By.css('.form-search-form input[type=radio]')); + if (radios.length <= nth) { + throw new RangeError('Index out of range to set a default search engine'); + } + await radios[nth].click(); + } +} diff --git a/e2e/lib/JSONOptionPage.ts b/e2e/lib/JSONOptionPage.ts new file mode 100644 index 0000000..ac1ae3d --- /dev/null +++ b/e2e/lib/JSONOptionPage.ts @@ -0,0 +1,22 @@ +import { Lanthan } from 'lanthan'; +import { WebDriver, By } from 'selenium-webdriver'; + +export default class JSONOptionPage { + private webdriver: WebDriver; + + constructor(lanthan: Lanthan) { + this.webdriver = lanthan.getWebDriver(); + } + + async updateSettings(value: string): Promise<void> { + let textarea = await this.webdriver.findElement(By.css('textarea')); + await this.webdriver.executeScript(`document.querySelector('textarea').value = '${value}'`) + await textarea.sendKeys(' '); + await this.webdriver.executeScript(() => document.querySelector('textarea')!!.blur()); + } + + async getErrorMessage(): Promise<string> { + let error = await this.webdriver.findElement(By.css('.settings-ui-input-error')); + return error.getText(); + } +} diff --git a/e2e/lib/OptionPage.ts b/e2e/lib/OptionPage.ts new file mode 100644 index 0000000..6b66f41 --- /dev/null +++ b/e2e/lib/OptionPage.ts @@ -0,0 +1,36 @@ +import { Lanthan } from 'lanthan'; +import { WebDriver, By } from 'selenium-webdriver'; +import JSONOptionPage from './JSONOptionPage'; +import FormOptionPage from './FormOptionPage'; + +export default class OptionPage { + private webdriver: WebDriver; + + constructor(private lanthan: Lanthan) { + this.webdriver = lanthan.getWebDriver(); + } + + static async open(lanthan: Lanthan) { + let url = await lanthan.getWebExtBrowser().runtime.getURL("build/settings.html") + await lanthan.getWebDriver().navigate().to(url); + return new OptionPage(lanthan); + } + + async switchToForm(): Promise<FormOptionPage> { + let useFormInput = await this.webdriver.findElement(By.css('#setting-source-form')); + await useFormInput.click(); + await this.webdriver.switchTo().alert().accept(); + return new FormOptionPage(this.lanthan); + } + + async asFormOptionPage(): Promise<FormOptionPage> { + // TODO validate current page + return new FormOptionPage(this.lanthan); + } + + async asJSONOptionPage(): Promise<JSONOptionPage> { + // TODO validate current page + return new JSONOptionPage(this.lanthan); + } +} + diff --git a/e2e/lib/Page.ts b/e2e/lib/Page.ts new file mode 100644 index 0000000..7a5dd7a --- /dev/null +++ b/e2e/lib/Page.ts @@ -0,0 +1,93 @@ +import { WebDriver, By, until } from 'selenium-webdriver'; +import { Console } from './Console'; + +type Hint = { + displayed: boolean, + text: string, +}; + +export default class Page { + private constructor(private webdriver: WebDriver) { + } + + static async currentContext(webdriver: WebDriver): Promise<Page> { + await Page.waitForConsoleLoaded(webdriver); + return new Page(webdriver); + } + + static async navigateTo(webdriver: WebDriver, url: string): Promise<Page> { + await webdriver.navigate().to(url); + await Page.waitForConsoleLoaded(webdriver); + return new Page(webdriver); + } + + async sendKeys(...keys: Array<string|number|Promise<string|number>>): Promise<void> { + let body = await this.webdriver.findElement(By.css('body')); + await body.sendKeys(...keys); + } + + async navigateTo(url: string): Promise<Page> { + await this.webdriver.navigate().to(url); + await Page.waitForConsoleLoaded(this.webdriver); + return new Page(this.webdriver); + } + + async showConsole(): Promise<Console> { + let iframe = this.webdriver.findElement(By.css('#vimvixen-console-frame')); + + await this.sendKeys(':'); + await this.webdriver.wait(until.elementIsVisible(iframe)); + await this.webdriver.switchTo().frame(0); + await this.webdriver.wait(until.elementLocated(By.css('input.vimvixen-console-command-input'))); + return new Console(this.webdriver); + } + + async getConsole(): Promise<Console> { + let iframe = this.webdriver.findElement(By.css('#vimvixen-console-frame')); + + await this.webdriver.wait(until.elementIsVisible(iframe)); + await this.webdriver.switchTo().frame(0); + return new Console(this.webdriver); + } + + async getScrollX(): Promise<number> { + return await this.webdriver.executeScript(() => window.pageXOffset); + } + + getScrollY(): Promise<number> { + return this.webdriver.executeScript(() => window.pageYOffset); + } + + scrollTo(x: number, y: number): Promise<void> { + return this.webdriver.executeScript(`window.scrollTo(${x}, ${y})`); + } + + pageHeight(): Promise<number> { + return this.webdriver.executeScript(() => window.document.documentElement.clientHeight); + } + + async waitAndGetHints(): Promise<Hint[]> { + await this.webdriver.wait(until.elementsLocated(By.css('.vimvixen-hint'))); + + let elements = await this.webdriver.findElements(By.css(`.vimvixen-hint`)); + let hints = []; + for (let e of elements) { + let display = await e.getCssValue('display'); + let text = await e.getText(); + hints.push({ + displayed: display !== 'none', + text: text, + }); + } + return hints; + } + + private static async waitForConsoleLoaded(webdriver: WebDriver) { + let topFrame = await webdriver.executeScript(() => window.top === window); + if (!topFrame) { + return; + } + await webdriver.wait(until.elementLocated(By.css('iframe.vimvixen-console-frame'))); + await new Promise(resolve => setTimeout(resolve, 100)); + } +} |