import * as path from "path"; import * as assert from "assert"; import TestServer from "./lib/TestServer"; import eventually from "./eventually"; import { Builder, Lanthan } from "lanthan"; import { WebDriver, Key } from "selenium-webdriver"; import Page from "./lib/Page"; const newApp = () => { const server = new TestServer(); server.receiveContent( "/", ` <!DOCTYPE html> <html lang="en"><body> <a href="hello">hello</a> </body></html>` ); server.receiveContent( "/follow-input", ` <!DOCTYPE html> <html lang="en"><body> <input> </body></html>` ); server.receiveContent( "/area", ` <!DOCTYPE html> <html lang="en"><body> <img width="256" height="256" usemap="#map" src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=" > <map name="map"> <area shape="rect" coords="0,0,64,64" href="/"> <area shape="rect" coords="64,64,64,64" href="/"> <area shape="rect" coords="128,128,64,64" href="/"> </map> </body></html>` ); /* * test case: link2 is out of the viewport * +-----------------+ * | [link1] |<--- window * | | * |=================|<--- viewport * | [link2] | * | | * +-----------------+ */ server.receiveContent( "/test1", ` <!DOCTYPE html> <html lang="en"><body> <div><a href="link1">link1</a></div> <div style="min-height:3000px"></div> <div><a href="link2">link2</a></div> </body></html>` ); /* * test case 2: link2 and link3 are out of window of the frame * +-----------------+ * | +-----------+ | * | | [link1] | | * |=================| * | | [link2] | | * | +-----------+ | * | | * +-----------------+ */ server.receiveContent( "/test2", ` <!DOCTYPE html> <html lang="en"><body> <iframe height="5000" src='/test2-frame'> </body></html>` ); server.receiveContent( "/test2-frame", ` <!DOCTYPE html> <html lang="en"><body> <div><a href="link1">link1</a></div> <div style="min-height:3000px"></div> <div><a href="link2">link2</a></div> </body></html>` ); /* test case 3: link2 is out of window of the frame * +-----------------+ * | +-----------+ | * | | [link1] | | * | +-----------+ | * | : [link2] : | * | + - - - - - + | * | | * +-----------------+ */ server.receiveContent( "/test3", ` <!DOCTYPE html> <html lang="en"><body> <iframe src='/test3-frame'> </body></html>` ); server.receiveContent( "/test3-frame", ` <!DOCTYPE html> <html lang="en"><body> <div><a href="link1">link1</a></div> <div style="min-height:3000px"></div> <div><a href="link2">link2</a></div> </body></html>` ); return server; }; describe("follow test", () => { const server = newApp(); let lanthan: Lanthan; let webdriver: WebDriver; let browser: any; before(async () => { lanthan = await Builder.forBrowser("firefox") .spyAddon(path.join(__dirname, "..")) .build(); webdriver = lanthan.getWebDriver(); browser = lanthan.getWebExtBrowser(); await server.start(); }); after(async () => { await server.stop(); if (lanthan) { await lanthan.quit(); } }); afterEach(async () => { const tabs = await browser.tabs.query({}); for (const tab of tabs.slice(1)) { await browser.tabs.remove(tab.id); } }); it("should focus an input by f", async () => { const page = await Page.navigateTo(webdriver, server.url("/follow-input")); await page.sendKeys("f"); await page.waitAndGetHints(); await page.sendKeys("a"); const tagName = (await webdriver.executeScript( () => document.activeElement!.tagName )) as string; assert.strictEqual(tagName.toLowerCase(), "input"); }); it("should open a link by f", async () => { const page = await Page.navigateTo(webdriver, server.url()); await page.sendKeys("f"); await page.waitAndGetHints(); await page.sendKeys("a"); await eventually(async () => { const hash = await webdriver.executeScript("return location.pathname"); assert.strictEqual(hash, "/hello"); }); }); it("should focus an input by F", async () => { const page = await Page.navigateTo(webdriver, server.url("/follow-input")); await page.sendKeys(Key.SHIFT, "f"); await page.waitAndGetHints(); await page.sendKeys("a"); const tagName = (await webdriver.executeScript( () => document.activeElement!.tagName )) as string; assert.strictEqual(tagName.toLowerCase(), "input"); }); it("should open a link to new tab by F", async () => { const page = await Page.navigateTo(webdriver, server.url()); await page.sendKeys(Key.SHIFT, "f"); await page.waitAndGetHints(); await page.sendKeys("a"); await eventually(async () => { const tabs = await browser.tabs.query({}); assert.strictEqual(tabs.length, 2); assert.strictEqual(new URL(tabs[1].url).pathname, "/hello"); assert.strictEqual(tabs[1].openerTabId, tabs[0].id); }); }); it("should show hints of links in area", async () => { const page = await Page.navigateTo(webdriver, server.url("/area")); await page.sendKeys(Key.SHIFT, "f"); const hints = await page.waitAndGetHints(); assert.strictEqual(hints.length, 3); }); it("should shows hints only in viewport", async () => { const page = await Page.navigateTo(webdriver, server.url("/test1")); await page.sendKeys(Key.SHIFT, "f"); const hints = await page.waitAndGetHints(); assert.strictEqual(hints.length, 1); }); it("should shows hints only in window of the frame", async () => { const page = await Page.navigateTo(webdriver, server.url("/test2")); await page.sendKeys(Key.SHIFT, "f"); await webdriver.switchTo().frame(0); const hints = await page.waitAndGetHints(); assert.strictEqual(hints.length, 1); }); it("should shows hints only in the frame", async () => { const page = await Page.navigateTo(webdriver, server.url("/test3")); await page.sendKeys(Key.SHIFT, "f"); await webdriver.switchTo().frame(0); const hints = await page.waitAndGetHints(); assert.strictEqual(hints.length, 1); }); });