Make pages as a page object

This commit is contained in:
Shin'ya Ueoka 2019-09-23 16:16:51 +09:00
parent b5540dea9a
commit d37896887e
29 changed files with 822 additions and 976 deletions

View file

@ -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();
}
}

64
e2e/lib/FormOptionPage.ts Normal file
View file

@ -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();
}
}

22
e2e/lib/JSONOptionPage.ts Normal file
View file

@ -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();
}
}

36
e2e/lib/OptionPage.ts Normal file
View file

@ -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);
}
}

93
e2e/lib/Page.ts Normal file
View file

@ -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));
}
}