diff options
Diffstat (limited to 'e2e/lib')
-rw-r--r-- | e2e/lib/Console.ts | 49 | ||||
-rw-r--r-- | e2e/lib/FormOptionPage.ts | 114 | ||||
-rw-r--r-- | e2e/lib/JSONOptionPage.ts | 20 | ||||
-rw-r--r-- | e2e/lib/OptionPage.ts | 16 | ||||
-rw-r--r-- | e2e/lib/Page.ts | 63 | ||||
-rw-r--r-- | e2e/lib/SettingRepository.ts | 13 | ||||
-rw-r--r-- | e2e/lib/TestServer.ts | 31 | ||||
-rw-r--r-- | e2e/lib/clipboard.ts | 73 |
8 files changed, 226 insertions, 153 deletions
diff --git a/e2e/lib/Console.ts b/e2e/lib/Console.ts index e3bd2d6..68c0e10 100644 --- a/e2e/lib/Console.ts +++ b/e2e/lib/Console.ts @@ -1,64 +1,73 @@ -import { WebDriver, By, Key } from 'selenium-webdriver'; +import { WebDriver, By, Key } from "selenium-webdriver"; export type CompletionItem = { type: string; text: string; highlight: boolean; -} +}; export class Console { - constructor(private webdriver: WebDriver) { - } + constructor(private webdriver: WebDriver) {} async sendKeys(...keys: string[]) { - const input = await this.webdriver.findElement(By.css('input')); + const input = await this.webdriver.findElement(By.css("input")); input.sendKeys(...keys); } async currentValue() { return await this.webdriver.executeScript(() => { - const input = document.querySelector('input'); + const input = document.querySelector("input"); if (input === null) { - throw new Error('could not find input element'); + throw new Error("could not find input element"); } return input.value; }); } async execCommand(command: string): Promise<void> { - const input = await this.webdriver.findElement(By.css('input.vimvixen-console-command-input')); + const input = await this.webdriver.findElement( + By.css("input.vimvixen-console-command-input") + ); await input.sendKeys(command, Key.ENTER); } async getErrorMessage(): Promise<string> { - const p = await this.webdriver.findElement(By.css('.vimvixen-console-error')); + const p = await this.webdriver.findElement( + By.css(".vimvixen-console-error") + ); return p.getText(); } async getInformationMessage(): Promise<string> { - const p = await this.webdriver.findElement(By.css('.vimvixen-console-info')); + const p = await this.webdriver.findElement( + By.css(".vimvixen-console-info") + ); return p.getText(); } async inputKeys(...keys: string[]) { - const input = await this.webdriver.findElement(By.css('input')); + const input = await this.webdriver.findElement(By.css("input")); await input.sendKeys(...keys); } getCompletions(): Promise<CompletionItem[]> { return this.webdriver.executeScript(() => { - const items = document.querySelectorAll('.vimvixen-console-completion > li'); + const items = document.querySelectorAll( + ".vimvixen-console-completion > li" + ); if (items.length === 0) { - throw new Error('completion items not found'); + throw new Error("completion items not found"); } const objs = []; for (const li of Array.from(items)) { - if (li.classList.contains('vimvixen-console-completion-title')) { - objs.push({ type: 'title', text: li.textContent!!.trim() }); - } else if ('vimvixen-console-completion-item') { - const highlight = li.classList.contains('vimvixen-completion-selected'); - objs.push({ type: 'item', text: li.textContent!!.trim(), highlight }); + if (li.classList.contains("vimvixen-console-completion-title")) { + objs.push({ type: "title", text: li.textContent!!.trim() }); + } else if ("vimvixen-console-completion-item") { + const highlight = li.classList.contains( + "vimvixen-completion-selected" + ); + objs.push({ type: "item", text: li.textContent!!.trim(), highlight }); } else { throw new Error(`unexpected class: ${li.className}`); } @@ -68,10 +77,10 @@ export class Console { } async close(): Promise<void> { - const input = await this.webdriver.findElement(By.css('input')); + const input = await this.webdriver.findElement(By.css("input")); await input.sendKeys(Key.ESCAPE); // TODO remove sleep - await new Promise(resolve => setTimeout(resolve, 100)); + 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 index 33ce2a7..5551684 100644 --- a/e2e/lib/FormOptionPage.ts +++ b/e2e/lib/FormOptionPage.ts @@ -1,5 +1,5 @@ -import { Lanthan } from 'lanthan'; -import { WebDriver, By, until } from 'selenium-webdriver'; +import { Lanthan } from "lanthan"; +import { WebDriver, By, until } from "selenium-webdriver"; export default class FormOptionPage { private webdriver: WebDriver; @@ -9,92 +9,136 @@ export default class FormOptionPage { } async setBlacklist(nth: number, url: string): Promise<void> { - const selector = '.form-blacklist-form-row > .column-url'; + const selector = ".form-blacklist-form-row > .column-url"; const inputs = await this.webdriver.findElements(By.css(selector)); if (inputs.length <= nth) { - throw new RangeError('Index out of range to set a blacklist') + throw new RangeError("Index out of range to set a blacklist"); } await inputs[nth].sendKeys(url); - await this.webdriver.executeScript(`document.querySelectorAll('${selector}')[${nth}].blur()`); + await this.webdriver.executeScript( + `document.querySelectorAll('${selector}')[${nth}].blur()` + ); } - async setPartialBlacklist(nth: number, url: string, keys: string): Promise<void> { - let selector = '.form-partial-blacklist-form-row > .column-url'; + async setPartialBlacklist( + nth: number, + url: string, + keys: string + ): Promise<void> { + let selector = ".form-partial-blacklist-form-row > .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 partial blacklist') + throw new RangeError("Index out of range to set a partial blacklist"); } await inputs[nth].sendKeys(url); - await this.webdriver.executeScript(`document.querySelectorAll('${selector}')[${nth}].blur()`); + await this.webdriver.executeScript( + `document.querySelectorAll('${selector}')[${nth}].blur()` + ); - selector = '.form-partial-blacklist-form-row > .column-keys'; + selector = ".form-partial-blacklist-form-row > .column-keys"; inputs = await this.webdriver.findElements(By.css(selector)); if (inputs.length <= nth) { - throw new RangeError('Index out of range to set a partial blacklist') + throw new RangeError("Index out of range to set a partial blacklist"); } await inputs[nth].sendKeys(keys); - await this.webdriver.executeScript(`document.querySelectorAll('${selector}')[${nth}].blur()`); + await this.webdriver.executeScript( + `document.querySelectorAll('${selector}')[${nth}].blur()` + ); } async setSearchEngine(nth: number, name: string, url: string) { - let selector = '.form-search-form-row > .column-name'; + let selector = ".form-search-form-row > .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') + 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()`); + await this.webdriver.executeScript( + `document.querySelectorAll('${selector}')[${nth}].blur()` + ); - selector = '.form-search-form-row > .column-url'; + selector = ".form-search-form-row > .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') + 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()`); + await this.webdriver.executeScript( + `document.querySelectorAll('${selector}')[${nth}].blur()` + ); } async addBlacklist(): Promise<void> { - const rows = await this.webdriver.findElements(By.css(`.form-blacklist-form-row`)); - const button = await this.webdriver.findElement(By.css('.form-blacklist-form .ui-add-button')) + const rows = await this.webdriver.findElements( + By.css(`.form-blacklist-form-row`) + ); + const button = await this.webdriver.findElement( + By.css(".form-blacklist-form .ui-add-button") + ); await button.click(); - await this.webdriver.wait(until.elementLocated(By.css(`.form-blacklist-form-row:nth-child(${rows.length + 1})`))); + await this.webdriver.wait( + until.elementLocated( + By.css(`.form-blacklist-form-row:nth-child(${rows.length + 1})`) + ) + ); } async addPartialBlacklist(): Promise<void> { - const rows = await this.webdriver.findElements(By.css(`.form-partial-blacklist-form-row`)); - const button = await this.webdriver.findElement(By.css('.form-partial-blacklist-form .ui-add-button')) + const rows = await this.webdriver.findElements( + By.css(`.form-partial-blacklist-form-row`) + ); + const button = await this.webdriver.findElement( + By.css(".form-partial-blacklist-form .ui-add-button") + ); await button.click(); - await this.webdriver.wait(until.elementLocated(By.css(`.form-partial-blacklist-form-row:nth-child(${rows.length + 2})`))); + await this.webdriver.wait( + until.elementLocated( + By.css(`.form-partial-blacklist-form-row:nth-child(${rows.length + 2})`) + ) + ); } async removeBlackList(nth: number): Promise<void> { - const buttons = await this.webdriver.findElements(By.css('.form-blacklist-form-row .ui-delete-button')); + const buttons = await this.webdriver.findElements( + By.css(".form-blacklist-form-row .ui-delete-button") + ); if (buttons.length <= nth) { - throw new RangeError('Index out of range to remove blacklist') + throw new RangeError("Index out of range to remove blacklist"); } - await buttons[nth].click() + await buttons[nth].click(); } async removePartialBlackList(nth: number): Promise<void> { - const buttons = await this.webdriver.findElements(By.css('.form-partial-blacklist-form-row .ui-delete-button')); + const buttons = await this.webdriver.findElements( + By.css(".form-partial-blacklist-form-row .ui-delete-button") + ); if (buttons.length <= nth) { - throw new RangeError('Index out of range to remove partial blacklist') + throw new RangeError("Index out of range to remove partial blacklist"); } - await buttons[nth].click() + await buttons[nth].click(); } async addSearchEngine(): Promise<void> { - const rows = await this.webdriver.findElements(By.css(`.form-search-form-row > .column-name`)); - const button = await this.webdriver.findElement(By.css('.form-search-form > .ui-add-button')) + const rows = await this.webdriver.findElements( + By.css(`.form-search-form-row > .column-name`) + ); + const button = await this.webdriver.findElement( + By.css(".form-search-form > .ui-add-button") + ); await button.click(); - await this.webdriver.wait(until.elementLocated(By.css(`.form-search-form-row:nth-child(${rows.length + 1})`))); + await this.webdriver.wait( + until.elementLocated( + By.css(`.form-search-form-row:nth-child(${rows.length + 1})`) + ) + ); } async setDefaultSearchEngine(nth: number): Promise<void> { - const radios = await this.webdriver.findElements(By.css('.form-search-form-row input[type=radio]')); + const radios = await this.webdriver.findElements( + By.css(".form-search-form-row input[type=radio]") + ); if (radios.length <= nth) { - throw new RangeError('Index out of range to set a default search engine'); + 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 index d6ed7ee..1c2db5b 100644 --- a/e2e/lib/JSONOptionPage.ts +++ b/e2e/lib/JSONOptionPage.ts @@ -1,5 +1,5 @@ -import { Lanthan } from 'lanthan'; -import { WebDriver, By } from 'selenium-webdriver'; +import { Lanthan } from "lanthan"; +import { WebDriver, By } from "selenium-webdriver"; export default class JSONOptionPage { private webdriver: WebDriver; @@ -9,14 +9,20 @@ export default class JSONOptionPage { } async updateSettings(value: string): Promise<void> { - const 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()); + const 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> { - const error = await this.webdriver.findElement(By.css('.settings-ui-input-error')); + const 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 index 9f994a0..e1ea759 100644 --- a/e2e/lib/OptionPage.ts +++ b/e2e/lib/OptionPage.ts @@ -1,7 +1,7 @@ -import { Lanthan } from 'lanthan'; -import { WebDriver, By } from 'selenium-webdriver'; -import JSONOptionPage from './JSONOptionPage'; -import FormOptionPage from './FormOptionPage'; +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; @@ -11,13 +11,17 @@ export default class OptionPage { } static async open(lanthan: Lanthan) { - const url = await lanthan.getWebExtBrowser().runtime.getURL("build/settings.html") + const url = await lanthan + .getWebExtBrowser() + .runtime.getURL("build/settings.html"); await lanthan.getWebDriver().navigate().to(url); return new OptionPage(lanthan); } async switchToForm(): Promise<FormOptionPage> { - const useFormInput = await this.webdriver.findElement(By.css('#setting-source-form')); + const useFormInput = await this.webdriver.findElement( + By.css("#setting-source-form") + ); await useFormInput.click(); await this.webdriver.switchTo().alert().accept(); return new FormOptionPage(this.lanthan); diff --git a/e2e/lib/Page.ts b/e2e/lib/Page.ts index 31605cb..85bda8d 100644 --- a/e2e/lib/Page.ts +++ b/e2e/lib/Page.ts @@ -1,19 +1,18 @@ -import { WebDriver, By, until } from 'selenium-webdriver'; -import { Console } from './Console'; +import { WebDriver, By, until } from "selenium-webdriver"; +import { Console } from "./Console"; type Hint = { - displayed: boolean, - text: string, + displayed: boolean; + text: string; }; type Selection = { - from: number, - to: number, + from: number; + to: number; }; export default class Page { - private constructor(private webdriver: WebDriver) { - } + private constructor(private webdriver: WebDriver) {} static async currentContext(webdriver: WebDriver): Promise<Page> { await Page.waitForConsoleLoaded(webdriver); @@ -26,8 +25,10 @@ export default class Page { return new Page(webdriver); } - async sendKeys(...keys: Array<string|number|Promise<string|number>>): Promise<void> { - const body = await this.webdriver.findElement(By.css('body')); + async sendKeys( + ...keys: Array<string | number | Promise<string | number>> + ): Promise<void> { + const body = await this.webdriver.findElement(By.css("body")); await body.sendKeys(...keys); } @@ -38,17 +39,23 @@ export default class Page { } async showConsole(): Promise<Console> { - const iframe = this.webdriver.findElement(By.css('#vimvixen-console-frame')); + const iframe = this.webdriver.findElement( + By.css("#vimvixen-console-frame") + ); - await this.sendKeys(':'); + 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'))); + await this.webdriver.wait( + until.elementLocated(By.css("input.vimvixen-console-command-input")) + ); return new Console(this.webdriver); } async getConsole(): Promise<Console> { - const iframe = this.webdriver.findElement(By.css('#vimvixen-console-frame')); + const iframe = this.webdriver.findElement( + By.css("#vimvixen-console-frame") + ); await this.webdriver.wait(until.elementIsVisible(iframe)); await this.webdriver.switchTo().frame(0); @@ -68,16 +75,22 @@ export default class Page { } pageHeight(): Promise<number> { - return this.webdriver.executeScript(() => window.document.documentElement.clientHeight); + return this.webdriver.executeScript( + () => window.document.documentElement.clientHeight + ); } async getSelection(): Promise<Selection> { - const obj = await this.webdriver.executeScript(`return window.getSelection();`) as any; + const obj = (await this.webdriver.executeScript( + `return window.getSelection();` + )) as any; return { from: obj.anchorOffset, to: obj.focusOffset }; } async clearSelection(): Promise<void> { - await this.webdriver.executeScript(`window.getSelection().removeAllRanges()`); + await this.webdriver.executeScript( + `window.getSelection().removeAllRanges()` + ); } async switchToTop(): Promise<void> { @@ -85,15 +98,17 @@ export default class Page { } async waitAndGetHints(): Promise<Hint[]> { - await this.webdriver.wait(until.elementsLocated(By.css('.vimvixen-hint'))); + await this.webdriver.wait(until.elementsLocated(By.css(".vimvixen-hint"))); - const elements = await this.webdriver.findElements(By.css(`.vimvixen-hint`)); + const elements = await this.webdriver.findElements( + By.css(`.vimvixen-hint`) + ); const hints = []; for (const e of elements) { - const display = await e.getCssValue('display'); + const display = await e.getCssValue("display"); const text = await e.getText(); hints.push({ - displayed: display !== 'none', + displayed: display !== "none", text: text, }); } @@ -105,7 +120,9 @@ export default class Page { if (!topFrame) { return; } - await webdriver.wait(until.elementLocated(By.css('iframe.vimvixen-console-frame'))); - await new Promise(resolve => setTimeout(resolve, 100)); + await webdriver.wait( + until.elementLocated(By.css("iframe.vimvixen-console-frame")) + ); + await new Promise((resolve) => setTimeout(resolve, 100)); } } diff --git a/e2e/lib/SettingRepository.ts b/e2e/lib/SettingRepository.ts index 3bdf6d2..87fb50b 100644 --- a/e2e/lib/SettingRepository.ts +++ b/e2e/lib/SettingRepository.ts @@ -1,18 +1,15 @@ -import { JSONTextSettings, SettingSource } from '../../src/shared/SettingData'; -import Settings from '../../src/shared/settings/Settings'; +import { JSONTextSettings, SettingSource } from "../../src/shared/SettingData"; +import Settings from "../../src/shared/settings/Settings"; export default class SettingRepository { - constructor( - private readonly browser: any, - ) { - } + constructor(private readonly browser: any) {} async saveJSON(settings: Settings): Promise<void> { await this.browser.storage.sync.set({ settings: { source: SettingSource.JSON, - json: JSONTextSettings.fromSettings(settings).toJSONText(), - } + json: JSONTextSettings.fromSettings(settings).toJSONText(), + }, }); } } diff --git a/e2e/lib/TestServer.ts b/e2e/lib/TestServer.ts index 5b9eee3..e0c711b 100644 --- a/e2e/lib/TestServer.ts +++ b/e2e/lib/TestServer.ts @@ -1,6 +1,6 @@ -import * as http from 'http'; -import * as net from 'net' -import express from 'express'; +import * as http from "http"; +import * as net from "net"; +import express from "express"; type HandlerFunc = (req: express.Request, res: express.Response) => void; @@ -9,10 +9,7 @@ export default class TestServer { private app: express.Application; - constructor( - private port = 0, - private address = '127.0.0.1', - ){ + constructor(private port = 0, private address = "127.0.0.1") { this.app = express(); } @@ -23,30 +20,30 @@ export default class TestServer { receiveContent(path: string, content: string): TestServer { this.app.get(path, (_req: express.Request, res: express.Response) => { - res.status(200).send(content) + res.status(200).send(content); }); return this; } - - url(path = '/'): string { + + url(path = "/"): string { if (!this.http) { - throw new Error('http server not started'); + throw new Error("http server not started"); } const addr = this.http.address() as net.AddressInfo; - return `http://${addr.address}:${addr.port}${path}` + return `http://${addr.address}:${addr.port}${path}`; } - start(): Promise<void> { + start(): Promise<void> { if (this.http) { - throw new Error('http server already started'); + throw new Error("http server already started"); } - this.http = http.createServer(this.app) + this.http = http.createServer(this.app); return new Promise((resolve) => { this.http!!.listen(this.port, this.address, () => { resolve(); - }) + }); }); } @@ -59,6 +56,6 @@ export default class TestServer { this.http = undefined; resolve(); }); - }) + }); } } diff --git a/e2e/lib/clipboard.ts b/e2e/lib/clipboard.ts index 297b71a..6cc94cb 100644 --- a/e2e/lib/clipboard.ts +++ b/e2e/lib/clipboard.ts @@ -1,18 +1,19 @@ -import { spawn } from 'child_process'; +import { spawn } from "child_process"; const readLinux = (): Promise<string> => { - let stdout = '', stderr = ''; + let stdout = "", + stderr = ""; return new Promise((resolve) => { - const xsel = spawn('xsel', ['--clipboard', '--output']); - xsel.stdout.on('data', (data) => { + const xsel = spawn("xsel", ["--clipboard", "--output"]); + xsel.stdout.on("data", (data) => { stdout += data; }); - xsel.stderr.on('data', (data) => { + xsel.stderr.on("data", (data) => { stderr += data; }); - xsel.on('close', (code) => { + xsel.on("close", (code) => { if (code !== 0) { - throw new Error(`xsel returns ${code}: ${stderr}`) + throw new Error(`xsel returns ${code}: ${stderr}`); } resolve(stdout); }); @@ -20,15 +21,15 @@ const readLinux = (): Promise<string> => { }; const writeLinux = (data: string): Promise<string> => { - let stderr = ''; + let stderr = ""; return new Promise((resolve) => { - const xsel = spawn('xsel', ['--clipboard', '--input']); - xsel.stderr.on('data', (data) => { + const xsel = spawn("xsel", ["--clipboard", "--input"]); + xsel.stderr.on("data", (data) => { stderr += data; }); - xsel.on('close', (code) => { + xsel.on("close", (code) => { if (code !== 0) { - throw new Error(`xsel returns ${code}: ${stderr}`) + throw new Error(`xsel returns ${code}: ${stderr}`); } resolve(); }); @@ -38,18 +39,19 @@ const writeLinux = (data: string): Promise<string> => { }; const readDarwin = (): Promise<string> => { - let stdout = '', stderr = ''; + let stdout = "", + stderr = ""; return new Promise((resolve) => { - const pbpaste = spawn('pbpaste'); - pbpaste.stdout.on('data', (data) => { + const pbpaste = spawn("pbpaste"); + pbpaste.stdout.on("data", (data) => { stdout += data; }); - pbpaste.stderr.on('data', (data) => { + pbpaste.stderr.on("data", (data) => { stderr += data; }); - pbpaste.on('close', (code) => { + pbpaste.on("close", (code) => { if (code !== 0) { - throw new Error(`pbpaste returns ${code}: ${stderr}`) + throw new Error(`pbpaste returns ${code}: ${stderr}`); } resolve(stdout); }); @@ -57,15 +59,15 @@ const readDarwin = (): Promise<string> => { }; const writeDarwin = (data: string): Promise<string> => { - let stderr = ''; + let stderr = ""; return new Promise((resolve) => { - const pbcopy = spawn('pbcopy'); - pbcopy.stderr.on('data', (data) => { + const pbcopy = spawn("pbcopy"); + pbcopy.stderr.on("data", (data) => { stderr += data; }); - pbcopy.on('close', (code) => { + pbcopy.on("close", (code) => { if (code !== 0) { - throw new Error(`pbcopy returns ${code}: ${stderr}`) + throw new Error(`pbcopy returns ${code}: ${stderr}`); } resolve(); }); @@ -83,25 +85,22 @@ class UnsupportedError extends Error { const read = () => { switch (process.platform) { - case 'linux': - return readLinux(); - case 'darwin': - return readDarwin(); + case "linux": + return readLinux(); + case "darwin": + return readDarwin(); } throw new UnsupportedError(process.platform); -} +}; const write = (data: string) => { switch (process.platform) { - case 'linux': - return writeLinux(data); - case 'darwin': - return writeDarwin(data); + case "linux": + return writeLinux(data); + case "darwin": + return writeDarwin(data); } throw new UnsupportedError(process.platform); -} - -export { - read, - write, }; + +export { read, write }; |