aboutsummaryrefslogtreecommitdiff
path: root/e2e
diff options
context:
space:
mode:
authorShin'ya Ueoka <ueokande@i-beam.org>2019-09-29 01:06:01 +0000
committerGitHub <noreply@github.com>2019-09-29 01:06:01 +0000
commit4f4396d0a69d33541844e723cad033b0a927333b (patch)
treef3a75c0b41d8fe2b1e6ca730501e36cee5701705 /e2e
parent0fc2eea7431649f85c6e5d57cca66457f24bb14d (diff)
parent9f0bc5732823505c91ce6b5ba3aa8e4b60ac93f6 (diff)
Merge pull request #648 from ueokande/migrate-to-latest-lanthan
Clean E2E tests
Diffstat (limited to 'e2e')
-rw-r--r--e2e/blacklist.test.js77
-rw-r--r--e2e/blacklist.test.ts62
-rw-r--r--e2e/clipboard.test.js123
-rw-r--r--e2e/clipboard.test.ts110
-rw-r--r--e2e/command_addbookmark.test.js67
-rw-r--r--e2e/command_addbookmark.test.ts51
-rw-r--r--e2e/command_bdelete.test.js203
-rw-r--r--e2e/command_bdelete.test.ts157
-rw-r--r--e2e/command_buffer.test.js202
-rw-r--r--e2e/command_buffer.test.ts162
-rw-r--r--e2e/command_open.test.js149
-rw-r--r--e2e/command_open.test.ts112
-rw-r--r--e2e/command_quit.test.js125
-rw-r--r--e2e/command_quit.test.ts93
-rw-r--r--e2e/command_tabopen.test.js160
-rw-r--r--e2e/command_tabopen.test.ts122
-rw-r--r--e2e/command_winopen.test.js172
-rw-r--r--e2e/command_winopen.test.ts133
-rw-r--r--e2e/completion.test.js136
-rw-r--r--e2e/completion.test.ts100
-rw-r--r--e2e/completion_buffers.test.js214
-rw-r--r--e2e/completion_buffers.test.ts180
-rw-r--r--e2e/completion_open.test.js255
-rw-r--r--e2e/completion_open.test.ts186
-rw-r--r--e2e/completion_set.test.js75
-rw-r--r--e2e/completion_set.test.ts64
-rw-r--r--e2e/console.test.js125
-rw-r--r--e2e/console.test.ts90
-rw-r--r--e2e/eventually.js23
-rw-r--r--e2e/eventually.ts30
-rw-r--r--e2e/follow.test.js257
-rw-r--r--e2e/follow.test.ts216
-rw-r--r--e2e/follow_properties.test.js182
-rw-r--r--e2e/follow_properties.test.ts142
-rw-r--r--e2e/lib/Console.js41
-rw-r--r--e2e/lib/Console.ts72
-rw-r--r--e2e/lib/FormOptionPage.ts68
-rw-r--r--e2e/lib/JSONOptionPage.ts22
-rw-r--r--e2e/lib/OptionPage.ts39
-rw-r--r--e2e/lib/Page.ts93
-rw-r--r--e2e/lib/TestServer.ts64
-rw-r--r--e2e/lib/clipboard.js63
-rw-r--r--e2e/lib/clipboard.ts107
-rw-r--r--e2e/mark.test.js121
-rw-r--r--e2e/mark.test.ts102
-rw-r--r--e2e/navigate.test.js274
-rw-r--r--e2e/navigate.test.ts254
-rw-r--r--e2e/options.test.js99
-rw-r--r--e2e/options.test.ts81
-rw-r--r--e2e/options_form.test.js125
-rw-r--r--e2e/options_form.test.ts86
-rw-r--r--e2e/repeat.test.js92
-rw-r--r--e2e/repeat.test.ts75
-rw-r--r--e2e/scroll.test.js150
-rw-r--r--e2e/scroll.test.ts137
-rw-r--r--e2e/settings.ts (renamed from e2e/settings.js)4
-rw-r--r--e2e/tab.test.js218
-rw-r--r--e2e/tab.test.ts211
-rw-r--r--e2e/zoom.test.js66
-rw-r--r--e2e/zoom.test.ts65
60 files changed, 3488 insertions, 3796 deletions
diff --git a/e2e/blacklist.test.js b/e2e/blacklist.test.js
deleted file mode 100644
index fa8e8db..0000000
--- a/e2e/blacklist.test.js
+++ /dev/null
@@ -1,77 +0,0 @@
-const express = require('express');
-const lanthan = require('lanthan');
-const path = require('path');
-const assert = require('assert');
-const settings = require('./settings');
-
-const newApp = () => {
- let app = express();
- app.get('/*', (req, res) => {
- res.status(200).send(`<!DOCTYPEhtml>
-<html lang="en">
- <body style="width:10000px; height:10000px"></body>
-</html>`);
- });
- return app;
-};
-
-describe("navigate test", () => {
-
- const port = 12321;
- let http;
- let firefox;
- let session;
- let browser;
-
- before(async() => {
- http = newApp().listen(port);
-
- firefox = await lanthan.firefox({
- spy: path.join(__dirname, '..'),
- builderf: (builder) => {
- builder.addFile('build/settings.js');
- },
- });
- session = firefox.session;
- browser = firefox.browser;
- });
-
- after(async() => {
- if (firefox) {
- await firefox.close();
- }
- http.close();
- });
-
- it('should disable add-on if the URL is in the blacklist', async () => {
- await browser.storage.local.set({
- settings: {
- source: 'json',
- json: `{
- "keymaps": {
- "j": { "type": "scroll.vertically", "count": 1 }
- },
- "blacklist": [ "127.0.0.1:${port}/a" ]
- }`,
- },
- });
-
- await session.navigateTo(`http://127.0.0.1:${port}/a`);
-
- let body = await session.findElementByCSS('body');
- await body.sendKeys('j');
-
- // not works
- let pageYOffset = await session.executeScript(() => window.pageYOffset);
- assert.equal(pageYOffset, 0);
-
- await session.navigateTo(`http://127.0.0.1:${port}/ab`);
- body = await session.findElementByCSS('body');
- await body.sendKeys('j');
-
- // works
- pageYOffset = await session.executeScript(() => window.pageYOffset);
- assert.equal(pageYOffset, 64);
- });
-});
-
diff --git a/e2e/blacklist.test.ts b/e2e/blacklist.test.ts
new file mode 100644
index 0000000..8bf1bd8
--- /dev/null
+++ b/e2e/blacklist.test.ts
@@ -0,0 +1,62 @@
+import * as path from 'path';
+import * as assert from 'assert';
+
+import TestServer from './lib/TestServer';
+import { Builder, Lanthan } from 'lanthan';
+import { WebDriver } from 'selenium-webdriver';
+import Page from './lib/Page';
+
+describe("blacklist test", () => {
+ let server = new TestServer().receiveContent('/*',
+ `<!DOCTYPE html><html lang="en"><body style="width:10000px; height:10000px"></body></html">`,
+ );
+ 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();
+
+ let url = server.url('/a').replace('http://', '');
+ await browser.storage.local.set({
+ settings: {
+ source: 'json',
+ json: `{
+ "keymaps": {
+ "j": { "type": "scroll.vertically", "count": 1 }
+ },
+ "blacklist": [ "${url}" ]
+ }`,
+ },
+ });
+ });
+
+ after(async() => {
+ await server.stop();
+ if (lanthan) {
+ await lanthan.quit();
+ }
+ });
+
+ it('should disable add-on if the URL is in the blacklist', async () => {
+ let page = await Page.navigateTo(webdriver, server.url('/a'));
+ await page.sendKeys('j')
+
+ let scrollY = await page.getScrollY();
+ assert.strictEqual(scrollY, 0);
+ });
+
+ it('should enabled add-on if the URL is not in the blacklist', async () => {
+ let page = await Page.navigateTo(webdriver, server.url('/ab'));
+ await page.sendKeys('j');
+
+ let scrollY = await page.getScrollY();
+ assert.strictEqual(scrollY, 64);
+ });
+});
diff --git a/e2e/clipboard.test.js b/e2e/clipboard.test.js
deleted file mode 100644
index 82e45fc..0000000
--- a/e2e/clipboard.test.js
+++ /dev/null
@@ -1,123 +0,0 @@
-const express = require('express');
-const lanthan = require('lanthan');
-const path = require('path');
-const assert = require('assert');
-const eventually = require('./eventually');
-const clipboard = require('./lib/clipboard');
-const settings = require('./settings');
-
-const Key = lanthan.Key;
-
-const newApp = () => {
- let app = express();
- app.get('/', (req, res) => {
- res.status(200).send(`<html lang="en"></html">`);
- });
- return app;
-};
-
-describe("navigate test", () => {
-
- const port = 12321;
- let http;
- let firefox;
- let session;
- let browser;
-
- before(async() => {
- http = newApp().listen(port);
-
- firefox = await lanthan.firefox({
- spy: path.join(__dirname, '..'),
- });
- session = firefox.session;
- browser = firefox.browser;
-
- await browser.storage.local.set({
- settings,
- });
- });
-
- after(async() => {
- if (firefox) {
- await firefox.close();
- }
- http.close();
- });
-
- beforeEach(async() => {
- let tabs = await browser.tabs.query({});
- for (let tab of tabs.slice(1)) {
- await browser.tabs.remove(tab.id);
- }
- })
-
- it('should copy current URL by y', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}/#should_copy_url`);
- let body = await session.findElementByCSS('body');
-
- await body.sendKeys('y');
- await eventually(async() => {
- let data = await clipboard.read();
- assert.equal(data, `http://127.0.0.1:${port}/#should_copy_url`);
- });
- });
-
- it('should open an URL from clipboard by p', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}/`);
- let body = await session.findElementByCSS('body');
-
- await clipboard.write(`http://127.0.0.1:${port}/#open_from_clipboard`);
- await body.sendKeys('p');
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({ active: true });
- assert.equal(tabs[0].url, `http://127.0.0.1:${port}/#open_from_clipboard`);
- });
- });
-
- it('should open an URL from clipboard to new tab by P', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}/`);
- let body = await session.findElementByCSS('body');
-
- await clipboard.write(`http://127.0.0.1:${port}/#open_to_new_tab`);
- await body.sendKeys(Key.Shift, 'p');
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({});
- assert.deepEqual(tabs.map(t => t.url), [
- `http://127.0.0.1:${port}/`,
- `http://127.0.0.1:${port}/#open_to_new_tab`,
- ]);
- });
- });
-
- it('should open search result with keywords in clipboard by p', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}/`);
- let body = await session.findElementByCSS('body');
-
- await clipboard.write(`an apple`);
- await body.sendKeys('p');
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({});
- assert.equal(tabs[0].url, `http://127.0.0.1:${port}/google?q=an%20apple`);
- });
- });
-
- it('should open search result with keywords in clipboard to new tabby P', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}/`);
- let body = await session.findElementByCSS('body');
-
- await clipboard.write(`an apple`);
- await body.sendKeys(Key.Shift, 'p');
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({});
- assert.deepEqual(tabs.map(t => t.url), [
- `http://127.0.0.1:${port}/`,
- `http://127.0.0.1:${port}/google?q=an%20apple`,
- ]);
- });
- });
-});
diff --git a/e2e/clipboard.test.ts b/e2e/clipboard.test.ts
new file mode 100644
index 0000000..2b71ade
--- /dev/null
+++ b/e2e/clipboard.test.ts
@@ -0,0 +1,110 @@
+import * as assert from 'assert';
+import * as path from 'path';
+
+import TestServer from './lib/TestServer';
+import eventually from './eventually';
+import * as clipboard from './lib/clipboard';
+import settings from './settings';
+import { Builder, Lanthan } from 'lanthan';
+import { WebDriver, Key } from 'selenium-webdriver';
+import Page from './lib/Page';
+
+describe("clipboard test", () => {
+ let server = new TestServer(12321).receiveContent('/happy', 'ok');
+ 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 browser.storage.local.set({
+ settings,
+ });
+
+ await server.start();
+ });
+
+ after(async() => {
+ await server.stop();
+ if (lanthan) {
+ await lanthan.quit();
+ }
+ });
+
+ beforeEach(async() => {
+ let tabs = await browser.tabs.query({});
+ for (let tab of tabs.slice(1)) {
+ await browser.tabs.remove(tab.id);
+ }
+ })
+
+ it('should copy current URL by y', async () => {
+ let page = await Page.navigateTo(webdriver, server.url('/#should_copy_url'));
+ await page.sendKeys('y');
+
+ await eventually(async() => {
+ let data = await clipboard.read();
+ assert.strictEqual(data, server.url('/#should_copy_url'));
+ });
+ });
+
+ it('should open an URL from clipboard by p', async () => {
+ await clipboard.write(server.url('/#open_from_clipboard'));
+
+ let page = await Page.navigateTo(webdriver, server.url());
+ await page.sendKeys('p');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({ active: true });
+ assert.strictEqual(tabs[0].url, server.url('/#open_from_clipboard'));
+ });
+ });
+
+ it('should open an URL from clipboard to new tab by P', async () => {
+ await clipboard.write(server.url('/#open_to_new_tab'));
+
+ let page = await Page.navigateTo(webdriver, server.url());
+ await page.sendKeys(Key.SHIFT, 'p');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({});
+ assert.deepStrictEqual(tabs.map((t: any) => t.url), [
+ server.url(),
+ server.url('/#open_to_new_tab'),
+ ]);
+ });
+ });
+
+ it('should open search result with keywords in clipboard by p', async () => {
+ await clipboard.write(`an apple`);
+
+ let page = await Page.navigateTo(webdriver, server.url());
+ await page.sendKeys(Key.SHIFT, 'p');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({ active: true });
+ assert.strictEqual(tabs[0].url, server.url('/google?q=an%20apple'));
+ });
+ });
+
+ it('should open search result with keywords in clipboard to new tabby P', async () => {
+ await clipboard.write(`an apple`);
+
+ let page = await Page.navigateTo(webdriver, server.url());
+ await page.sendKeys(Key.SHIFT, 'p');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({});
+ assert.deepStrictEqual(tabs.map((t: any) => t.url), [
+ server.url(),
+ server.url('/google?q=an%20apple'),
+ ]);
+ });
+ });
+});
diff --git a/e2e/command_addbookmark.test.js b/e2e/command_addbookmark.test.js
deleted file mode 100644
index e8995bc..0000000
--- a/e2e/command_addbookmark.test.js
+++ /dev/null
@@ -1,67 +0,0 @@
-const express = require('express');
-const lanthan = require('lanthan');
-const path = require('path');
-const assert = require('assert');
-const eventually = require('./eventually');
-
-const Key = lanthan.Key;
-
-const newApp = () => {
- let app = express();
- app.get('/happy', (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<html lang="en">
- <head>
- <title>how to be happy</title>
- </head>
-</html">`);
- });
- return app;
-};
-
-describe('addbookmark command test', () => {
- const port = 12321;
- let http;
- let firefox;
- let session;
- let browser;
-
- before(async() => {
- http = newApp().listen(port);
-
- firefox = await lanthan.firefox({
- spy: path.join(__dirname, '..'),
- builderf: (builder) => {
- builder.addFile('build/settings.js');
- },
- });
- session = firefox.session;
- browser = firefox.browser;
- });
-
- after(async() => {
- http.close();
- if (firefox) {
- await firefox.close();
- }
- });
-
- beforeEach(async() => {
- await session.navigateTo(`http://127.0.0.1:${port}/happy`);
- });
-
- it('should add a bookmark from the current page', async() => {
- let body = await session.findElementByCSS('body');
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- await input.sendKeys('addbookmark how to be happy', Key.Enter);
-
- await eventually(async() => {
- var bookmarks = await browser.bookmarks.search({ title: 'how to be happy' });
- assert.equal(bookmarks.length, 1);
- assert.equal(bookmarks[0].url, `http://127.0.0.1:${port}/happy`);
- });
- });
-});
diff --git a/e2e/command_addbookmark.test.ts b/e2e/command_addbookmark.test.ts
new file mode 100644
index 0000000..bcc75ac
--- /dev/null
+++ b/e2e/command_addbookmark.test.ts
@@ -0,0 +1,51 @@
+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 } from 'selenium-webdriver';
+import Page from './lib/Page';
+
+describe('addbookmark command test', () => {
+ let server = new TestServer().receiveContent('/happy', `
+ <!DOCTYPE html>
+ <html lang="en"><head><title>how to be happy</title></head></html">`,
+ );
+ 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();
+ }
+ });
+
+ beforeEach(async() => {
+ await webdriver.navigate().to(server.url('/happy'));
+ });
+
+ it('should add a bookmark from the current page', async() => {
+ let page = await Page.currentContext(webdriver);
+ let console = await page.showConsole();
+ await console.execCommand('addbookmark how to be happy');
+
+ await eventually(async() => {
+ var bookmarks = await browser.bookmarks.search({ title: 'how to be happy' });
+ assert.strictEqual(bookmarks.length, 1);
+ assert.strictEqual(bookmarks[0].url, server.url('/happy'));
+ });
+ });
+});
diff --git a/e2e/command_bdelete.test.js b/e2e/command_bdelete.test.js
deleted file mode 100644
index 1f416db..0000000
--- a/e2e/command_bdelete.test.js
+++ /dev/null
@@ -1,203 +0,0 @@
-const express = require('express');
-const lanthan = require('lanthan');
-const path = require('path');
-const assert = require('assert');
-const eventually = require('./eventually');
-
-const Key = lanthan.Key;
-
-const newApp = () => {
- let app = express();
- app.get('/*', (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<html lang="en">
- <head>
- <title>my_${req.path.slice(1)}</title>
- </head>
- <body><h1>${req.path}</h1></body>
-</html">`);
- });
- return app;
-};
-
-describe('bdelete/bdeletes command test', () => {
- const port = 12321;
- let http;
- let firefox;
- let session;
- let browser;
-
- before(async() => {
- http = newApp().listen(port);
-
- firefox = await lanthan.firefox({
- spy: path.join(__dirname, '..'),
- builderf: (builder) => {
- builder.addFile('build/settings.js');
- },
- });
- session = firefox.session;
- browser = firefox.browser;
- });
-
- after(async() => {
- http.close();
- if (firefox) {
- await firefox.close();
- }
- });
-
- beforeEach(async() => {
- let tabs = await browser.tabs.query({});
- for (let tab of tabs.slice(1)) {
- await browser.tabs.remove(tab.id);
- }
- await browser.tabs.update(tabs[0].id, { url: `http://127.0.0.1:${port}/site1`, pinned: true });
- await browser.tabs.create({ url: `http://127.0.0.1:${port}/site2`, pinned: true })
- await browser.tabs.create({ url: `http://127.0.0.1:${port}/site3`, pinned: true })
- await browser.tabs.create({ url: `http://127.0.0.1:${port}/site4` })
- await browser.tabs.create({ url: `http://127.0.0.1:${port}/site5` })
-
- await eventually(async() => {
- let handles = await session.getWindowHandles();
- assert.equal(handles.length, 5);
- await session.switchToWindow(handles[2]);
- await session.findElementByCSS('iframe');
- });
-
- await new Promise((resolve) => setTimeout(resolve, 100));
- });
-
- it('should delete an unpinned tab by bdelete command', async() => {
- let body = await session.findElementByCSS('body');
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- await input.sendKeys('bdelete site5', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({});
- assert.deepEqual(tabs.map(t => t.url), [
- `http://127.0.0.1:${port}/site1`,
- `http://127.0.0.1:${port}/site2`,
- `http://127.0.0.1:${port}/site3`,
- `http://127.0.0.1:${port}/site4`,
- ])
- });
- });
-
- it('should not delete an pinned tab by bdelete command by bdelete command', async() => {
- let body = await session.findElementByCSS('body');
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- await input.sendKeys('bdelete site1', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({});
- assert.equal(tabs.length, 5);
- });
- });
-
- it('should show an error when no tabs are matched by bdelete command', async() => {
- let body = await session.findElementByCSS('body');
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- await input.sendKeys('bdelete xyz', Key.Enter);
-
- await eventually(async() => {
- let p = await session.findElementByCSS('.vimvixen-console-error');
- let text = await p.getText();
- assert.equal(text, 'No matching buffer for xyz');
- });
- });
-
- it('should show an error when more than one tabs are matched by bdelete command', async() => {
- let body = await session.findElementByCSS('body');
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- await input.sendKeys('bdelete site', Key.Enter);
-
- await eventually(async() => {
- let p = await session.findElementByCSS('.vimvixen-console-error');
- let text = await p.getText();
- assert.equal(text, 'More than one match for site');
- });
- });
-
- it('should delete an unpinned tab by bdelete! command', async() => {
- let body = await session.findElementByCSS('body');
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- await input.sendKeys('bdelete! site5', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({});
- assert.deepEqual(tabs.map(t => t.url), [
- `http://127.0.0.1:${port}/site1`,
- `http://127.0.0.1:${port}/site2`,
- `http://127.0.0.1:${port}/site3`,
- `http://127.0.0.1:${port}/site4`,
- ])
- });
- });
-
- it('should delete an pinned tab by bdelete! command', async() => {
- let body = await session.findElementByCSS('body');
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- await input.sendKeys('bdelete! site1', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({});
- assert.deepEqual(tabs.map(t => t.url), [
- `http://127.0.0.1:${port}/site2`,
- `http://127.0.0.1:${port}/site3`,
- `http://127.0.0.1:${port}/site4`,
- `http://127.0.0.1:${port}/site5`,
- ])
- });
- });
-
- it('should delete unpinned tabs by bdeletes command', async() => {
- let body = await session.findElementByCSS('body');
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- await input.sendKeys('bdeletes site', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({});
- assert.deepEqual(tabs.map(t => t.url), [
- `http://127.0.0.1:${port}/site1`,
- `http://127.0.0.1:${port}/site2`,
- `http://127.0.0.1:${port}/site3`,
- ])
- });
- });
-
- it('should delete both pinned and unpinned tabs by bdeletes! command', async() => {
- let body = await session.findElementByCSS('body');
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- await input.sendKeys('bdeletes! site', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({});
- assert.equal(tabs.length, 1);
- });
- });
-});
diff --git a/e2e/command_bdelete.test.ts b/e2e/command_bdelete.test.ts
new file mode 100644
index 0000000..c96034d
--- /dev/null
+++ b/e2e/command_bdelete.test.ts
@@ -0,0 +1,157 @@
+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 } from 'selenium-webdriver';
+import Page from './lib/Page';
+
+describe('bdelete/bdeletes command test', () => {
+ let server = new TestServer().receiveContent('/*', 'ok');
+ 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();
+ }
+ });
+
+ beforeEach(async() => {
+ let tabs = await browser.tabs.query({});
+ for (let tab of tabs.slice(1)) {
+ await browser.tabs.remove(tab.id);
+ }
+ await browser.tabs.update(tabs[0].id, { url: server.url('/site1'), pinned: true });
+ await browser.tabs.create({ url: server.url('/site2'), pinned: true })
+ await browser.tabs.create({ url: server.url('/site3'), pinned: true })
+ await browser.tabs.create({ url: server.url('/site4'), })
+ await browser.tabs.create({ url: server.url('/site5'), })
+
+ await eventually(async() => {
+ let handles = await webdriver.getAllWindowHandles();
+ assert.strictEqual(handles.length, 5);
+ await webdriver.switchTo().window(handles[2]);
+ });
+ });
+
+ it('should delete an unpinned tab by bdelete command', async() => {
+ let page = await Page.currentContext(webdriver);
+ let console = await page.showConsole();
+ await console.execCommand('bdelete site5');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({});
+ assert.deepStrictEqual(tabs.map((t: any) => t.url), [
+ server.url('/site1'),
+ server.url('/site2'),
+ server.url('/site3'),
+ server.url('/site4'),
+ ])
+ });
+ });
+
+ it('should not delete an pinned tab by bdelete command by bdelete command', async() => {
+ let page = await Page.currentContext(webdriver);
+ let console = await page.showConsole();
+ await console.execCommand('bdelete site1');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({});
+ assert.strictEqual(tabs.length, 5);
+ });
+ });
+
+ it('should show an error when no tabs are matched by bdelete command', async() => {
+ let page = await Page.currentContext(webdriver);
+ let console = await page.showConsole();
+ await console.execCommand('bdelete xyz');
+
+ await eventually(async() => {
+ let text = await console.getErrorMessage();
+ assert.strictEqual(text, 'No matching buffer for xyz');
+ });
+ });
+
+ it('should show an error when more than one tabs are matched by bdelete command', async() => {
+ let page = await Page.currentContext(webdriver);
+ let console = await page.showConsole();
+ await console.execCommand('bdelete site');
+
+ await eventually(async() => {
+ let text = await console.getErrorMessage();
+ assert.strictEqual(text, 'More than one match for site');
+ });
+ });
+
+ it('should delete an unpinned tab by bdelete! command', async() => {
+ let page = await Page.currentContext(webdriver);
+ let console = await page.showConsole();
+ await console.execCommand('bdelete! site5');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({});
+ assert.deepStrictEqual(tabs.map((t: any) => t.url), [
+ server.url('/site1'),
+ server.url('/site2'),
+ server.url('/site3'),
+ server.url('/site4'),
+ ])
+ });
+ });
+
+ it('should delete an pinned tab by bdelete! command', async() => {
+ let page = await Page.currentContext(webdriver);
+ let console = await page.showConsole();
+ await console.execCommand('bdelete! site1');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({});
+ assert.deepStrictEqual(tabs.map((t: any) => t.url), [
+ server.url('/site2'),
+ server.url('/site3'),
+ server.url('/site4'),
+ server.url('/site5'),
+ ])
+ });
+ });
+
+ it('should delete unpinned tabs by bdeletes command', async() => {
+ let page = await Page.currentContext(webdriver);
+ let console = await page.showConsole();
+ await console.execCommand('bdeletes site');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({});
+ assert.deepStrictEqual(tabs.map((t: any) => t.url), [
+ server.url('/site1'),
+ server.url('/site2'),
+ server.url('/site3'),
+ ])
+ });
+ });
+
+ it('should delete both pinned and unpinned tabs by bdeletes! command', async() => {
+ let page = await Page.currentContext(webdriver);
+ let console = await page.showConsole();
+ await console.execCommand('bdeletes! site');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({});
+ assert.strictEqual(tabs.length, 1);
+ });
+ });
+});
diff --git a/e2e/command_buffer.test.js b/e2e/command_buffer.test.js
deleted file mode 100644
index bf94428..0000000
--- a/e2e/command_buffer.test.js
+++ /dev/null
@@ -1,202 +0,0 @@
-const express = require('express');
-const lanthan = require('lanthan');
-const path = require('path');
-const assert = require('assert');
-const eventually = require('./eventually');
-
-const Key = lanthan.Key;
-
-const newApp = () => {
- let app = express();
- app.get('/*', (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<html lang="en">
- <head>
- <title>my_${req.path.slice(1)}</title>
- </head>
- <body><h1>${req.path}</h1></body>
-</html">`);
- });
- return app;
-};
-
-describe('buffer command test', () => {
- const port = 12321;
- let http;
- let firefox;
- let session;
- let browser;
-
- before(async() => {
- http = newApp().listen(port);
-
- firefox = await lanthan.firefox({
- spy: path.join(__dirname, '..'),
- builderf: (builder) => {
- builder.addFile('build/settings.js');
- },
- });
- session = firefox.session;
- browser = firefox.browser;
- });
-
- after(async() => {
- http.close();
- if (firefox) {
- await firefox.close();
- }
- });
-
- beforeEach(async() => {
- let tabs = await browser.tabs.query({});
- for (let tab of tabs.slice(1)) {
- await browser.tabs.remove(tab.id);
- }
- await browser.tabs.update(tabs[0].id, { url: `http://127.0.0.1:${port}/site1` });
- for (let i = 2; i <= 5; ++i) {
- await browser.tabs.create({ url: `http://127.0.0.1:${port}/site${i}`})
- }
-
- await eventually(async() => {
- let handles = await session.getWindowHandles();
- assert.equal(handles.length, 5);
- await session.switchToWindow(handles[2]);
- await session.findElementByCSS('iframe');
- });
-
- await new Promise((resolve) => setTimeout(resolve, 100));
- });
-
- it('should do nothing by buffer command with no parameters', async() => {
- let body = await session.findElementByCSS('body');
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- await input.sendKeys('buffer', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({ active: true });
- assert.equal(tabs[0].index, 2);
- });
- });
-
- it('should select a tab by buffer command with a number', async() => {
- let body = await session.findElementByCSS('body');
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- await input.sendKeys('buffer', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({ active: true });
- assert.equal(tabs[0].index, 2);
- });
- });
-
- it('should should an out of range error by buffer commands', async() => {
- let body = await session.findElementByCSS('body');
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- await input.sendKeys('buffer 0', Key.Enter);
-
- await eventually(async() => {
- let p = await session.findElementByCSS('.vimvixen-console-error');
- let text = await p.getText();
- assert.equal(text, 'tab 0 does not exist');
- });
-
- await session.switchToParentFrame();
- body = await session.findElementByCSS('body');
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- input = await session.findElementByCSS('input');
- await input.sendKeys('buffer 9', Key.Enter);
-
- await eventually(async() => {
- let p = await session.findElementByCSS('.vimvixen-console-error');
- let text = await p.getText();
- assert.equal(text, 'tab 9 does not exist');
- });
- });
-
- it('should select a tab by buffer command with a title', async() => {
- let body = await session.findElementByCSS('body');
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- await input.sendKeys('buffer my_site1', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({ active: true });
- assert.equal(tabs[0].index, 0);
- });
- });
-
- it('should select a tab by buffer command with an URL', async() => {
- let body = await session.findElementByCSS('body');
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- await input.sendKeys('buffer /site1', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({ active: true });
- assert.equal(tabs[0].index, 0);
- });
- });
-
- it('should select tabs rotately', async() => {
- let handles = await session.getWindowHandles();
- await session.switchToWindow(handles[4]);
-
- let body = await session.findElementByCSS('body');
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- await input.sendKeys('buffer site', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({ active: true });
- assert.equal(tabs[0].index, 0);
- });
- });
-
- it('should do nothing by ":buffer %"', async() => {
- let body = await session.findElementByCSS('body');
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- await input.sendKeys('buffer %', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({ active: true });
- assert.equal(tabs[0].index, 2);
- });
- });
-
- it('should selects last selected tab by ":buffer #"', async() => {
- let handles = await session.getWindowHandles();
- await session.switchToWindow(handles[1]);
-
- let body = await session.findElementByCSS('body');
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- await input.sendKeys('buffer #', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({ active: true });
- assert.equal(tabs[0].index, 2);
- });
- });
-});
diff --git a/e2e/command_buffer.test.ts b/e2e/command_buffer.test.ts
new file mode 100644
index 0000000..0036839
--- /dev/null
+++ b/e2e/command_buffer.test.ts
@@ -0,0 +1,162 @@
+import * as path from 'path';
+import * as assert from 'assert';
+import { Request, Response } from 'express';
+
+import TestServer from './lib/TestServer';
+import eventually from './eventually';
+import { Builder, Lanthan } from 'lanthan';
+import { WebDriver } from 'selenium-webdriver';
+import Page from './lib/Page';
+
+describe('buffer command test', () => {
+ let server = new TestServer().handle('/*', (req: Request, res: Response) => {
+ res.send(`
+ <!DOCTYPE html>
+ <html lang="en">
+ <head>
+ <title>my_${req.path.slice(1)}</title>
+ </head>
+ </html">`);
+ });
+ 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();
+ }
+ });
+
+ beforeEach(async() => {
+ let tabs = await browser.tabs.query({});
+ for (let tab of tabs.slice(1)) {
+ await browser.tabs.remove(tab.id);
+ }
+ await browser.tabs.update(tabs[0].id, { url: server.url('/site1') });
+ for (let i = 2; i <= 5; ++i) {
+ await browser.tabs.create({ url: server.url('/site' + i) });
+ }
+
+ await eventually(async() => {
+ let handles = await webdriver.getAllWindowHandles();
+ assert.strictEqual(handles.length, 5);
+ await webdriver.switchTo().window(handles[2]);
+ });
+ });
+
+ it('should do nothing by buffer command with no parameters', async() => {
+ let page = await Page.currentContext(webdriver);
+ let console = await page.showConsole();
+ await console.execCommand('buffer');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({ active: true });
+ assert.strictEqual(tabs[0].index, 2);
+ });
+ });
+
+ it('should select a tab by buffer command with a number', async() => {
+ let page = await Page.currentContext(webdriver);
+ let console = await page.showConsole();
+ await console.execCommand('buffer 1');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({ active: true });
+ assert.strictEqual(tabs[0].index, 0);
+ });
+ });
+
+ it('should should an out of range error by buffer commands', async() => {
+ let page = await Page.currentContext(webdriver);
+ let console = await page.showConsole();
+ await console.execCommand('buffer 0');
+
+ await eventually(async() => {
+ let text = await console.getErrorMessage();
+ assert.strictEqual(text, 'tab 0 does not exist');
+ });
+
+ await (webdriver.switchTo() as any).parentFrame();
+
+ console = await page.showConsole();
+ await console.execCommand('buffer 9');
+
+ await eventually(async() => {
+ let text = await console.getErrorMessage();
+ assert.strictEqual(text, 'tab 9 does not exist');
+ });
+ });
+
+ it('should select a tab by buffer command with a title', async() => {
+ let page = await Page.currentContext(webdriver);
+ let console = await page.showConsole();
+ await console.execCommand('buffer my_site1');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({ active: true });
+ assert.strictEqual(tabs[0].index, 0);
+ });
+ });
+
+ it('should select a tab by buffer command with an URL', async() => {
+ let page = await Page.currentContext(webdriver);
+ let console = await page.showConsole();
+ await console.execCommand('buffer /site1');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({ active: true });
+ assert.strictEqual(tabs[0].index, 0);
+ });
+ });
+
+ it('should select tabs rotately', async() => {
+ let handles = await webdriver.getAllWindowHandles();
+ await webdriver.switchTo().window(handles[4]);
+
+ let page = await Page.currentContext(webdriver);
+ let console = await page.showConsole();
+ await console.execCommand('buffer site');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({ active: true });
+ assert.strictEqual(tabs[0].index, 0);
+ });
+ });
+
+ it('should do nothing by ":buffer %"', async() => {
+ let page = await Page.currentContext(webdriver);
+ let console = await page.showConsole();
+ await console.execCommand('buffer %');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({ active: true });
+ assert.strictEqual(tabs[0].index, 2);
+ });
+ });
+
+ it('should selects last selected tab by ":buffer #"', async() => {
+ let handles = await webdriver.getAllWindowHandles();
+ await webdriver.switchTo().window(handles[1]);
+
+ let page = await Page.currentContext(webdriver);
+ let console = await page.showConsole();
+ await console.execCommand('buffer #');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({ active: true });
+ assert.strictEqual(tabs[0].index, 2);
+ });
+ });
+});
diff --git a/e2e/command_open.test.js b/e2e/command_open.test.js
deleted file mode 100644
index 0d41f96..0000000
--- a/e2e/command_open.test.js
+++ /dev/null
@@ -1,149 +0,0 @@
-const express = require('express');
-const lanthan = require('lanthan');
-const path = require('path');
-const assert = require('assert');
-const eventually = require('./eventually');
-const settings = require('./settings');
-
-const Key = lanthan.Key;
-
-const newApp = () => {
-
- let app = express();
- for (let name of ['google', 'yahoo', 'bing', 'duckduckgo', 'twitter', 'wikipedia']) {
- app.get('/' + name, (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<html lang="en">
- <body><h1>${name.charAt(0).toUpperCase() + name.slice(1)}</h1></body>
-</html">`);
- });
- }
- app.get('/', (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<html lang="en">
- <body><h1>home</h1></body>
-</html">`);
- });
- return app;
-};
-
-describe("open command test", () => {
- const port = 12321;
- let http;
- let firefox;
- let session;
- let browser;
- let body;
-
- before(async() => {
- firefox = await lanthan.firefox({
- spy: path.join(__dirname, '..'),
- builderf: (builder) => {
- builder.addFile('build/settings.js');
- },
- });
- session = firefox.session;
- browser = firefox.browser;
- http = newApp().listen(port);
-
- await browser.storage.local.set({
- settings,
- });
- });
-
- after(async() => {
- http.close();
- if (firefox) {
- await firefox.close();
- }
- });
-
- beforeEach(async() => {
- await session.navigateTo(`http://127.0.0.1:${port}`);
- body = await session.findElementByCSS('body');
- })
-
- it('should open default search for keywords by open command ', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- input.sendKeys('open an apple', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({ active: true });
- let url = new URL(tabs[0].url);
- assert.equal(url.href, `http://127.0.0.1:${port}/google?q=an%20apple`)
- });
- });
-
- it('should open certain search page for keywords by open command ', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- input.sendKeys('open yahoo an apple', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({ active: true })
- let url = new URL(tabs[0].url);
- assert.equal(url.href, `http://127.0.0.1:${port}/yahoo?q=an%20apple`)
- });
- });
-
- it('should open default engine with empty keywords by open command ', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- input.sendKeys('open', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({ active: true })
- let url = new URL(tabs[0].url);
- assert.equal(url.href, `http://127.0.0.1:${port}/google?q=`)
- });
- });
-
- it('should open certain search page for empty keywords by open command ', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- input.sendKeys('open yahoo', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({ active: true })
- let url = new URL(tabs[0].url);
- assert.equal(url.href, `http://127.0.0.1:${port}/yahoo?q=`)
- });
- });
-
- it('should open a site with domain by open command ', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- input.sendKeys('open i-beam.org', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({ active: true })
- let url = new URL(tabs[0].url);
- assert.equal(url.href, 'https://i-beam.org/')
- });
- });
-
- it('should open a site with URL by open command ', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- input.sendKeys('open https://i-beam.org', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({ active: true })
- let url = new URL(tabs[0].url);
- assert.equal(url.href, 'https://i-beam.org/')
- });
- });
-});
diff --git a/e2e/command_open.test.ts b/e2e/command_open.test.ts
new file mode 100644
index 0000000..6fb2645
--- /dev/null
+++ b/e2e/command_open.test.ts
@@ -0,0 +1,112 @@
+import * as path from 'path';
+import * as assert from 'assert';
+
+import TestServer from './lib/TestServer';
+import settings from './settings';
+import eventually from './eventually';
+import { Builder, Lanthan } from 'lanthan';
+import { WebDriver } from 'selenium-webdriver';
+import Page from './lib/Page';
+
+describe("open command test", () => {
+ let server = new TestServer(12321)
+ .receiveContent('/google', 'google')
+ .receiveContent('/yahoo', 'yahoo');
+ let lanthan: Lanthan;
+ let webdriver: WebDriver;
+ let browser: any;
+ let page: Page;
+
+ before(async() => {
+ lanthan = await Builder
+ .forBrowser('firefox')
+ .spyAddon(path.join(__dirname, '..'))
+ .build();
+ webdriver = lanthan.getWebDriver();
+ browser = lanthan.getWebExtBrowser();
+
+ await browser.storage.local.set({
+ settings,
+ });
+
+ await server.start();
+ });
+
+ after(async() => {
+ await server.stop();
+ if (lanthan) {
+ await lanthan.quit();
+ }
+ });
+
+ beforeEach(async() => {
+ await webdriver.switchTo().defaultContent();
+ page = await Page.navigateTo(webdriver, server.url());
+ })
+
+ it('should open default search for keywords by open command ', async() => {
+ let console = await page.showConsole();
+ await console.execCommand('open an apple');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({ active: true });
+ let url = new URL(tabs[0].url);
+ assert.strictEqual(url.href, server.url('/google?q=an%20apple'))
+ });
+ });
+
+ it('should open certain search page for keywords by open command ', async() => {
+ let console = await page.showConsole();
+ await console.execCommand('open yahoo an apple');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({ active: true })
+ let url = new URL(tabs[0].url);
+ assert.strictEqual(url.href, server.url('/yahoo?q=an%20apple'))
+ });
+ });
+
+ it('should open default engine with empty keywords by open command ', async() => {
+ let console = await page.showConsole();
+ await console.execCommand('open');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({ active: true })
+ let url = new URL(tabs[0].url);
+ assert.strictEqual(url.href, server.url('/google?q='))
+ });
+ });
+
+ it('should open certain search page for empty keywords by open command ', async() => {
+ let console = await page.showConsole();
+ await console.execCommand('open yahoo');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({ active: true })
+ let url = new URL(tabs[0].url);
+ assert.strictEqual(url.href, server.url('/yahoo?q='))
+ });
+ });
+
+ it('should open a site with domain by open command ', async() => {
+ let console = await page.showConsole();
+ await console.execCommand('open example.com');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({ active: true })
+ let url = new URL(tabs[0].url);
+ assert.strictEqual(url.href, 'http://example.com/')
+ });
+ });
+
+ it('should open a site with URL by open command ', async() => {
+ let console = await page.showConsole();
+ await console.execCommand('open https://example.com/');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({ active: true })
+ let url = new URL(tabs[0].url);
+ assert.strictEqual(url.href, 'https://example.com/')
+ });
+ });
+});
diff --git a/e2e/command_quit.test.js b/e2e/command_quit.test.js
deleted file mode 100644
index ee4c2d8..0000000
--- a/e2e/command_quit.test.js
+++ /dev/null
@@ -1,125 +0,0 @@
-const express = require('express');
-const lanthan = require('lanthan');
-const path = require('path');
-const assert = require('assert');
-const eventually = require('./eventually');
-
-const Key = lanthan.Key;
-
-const newApp = () => {
- let app = express();
- app.get('/*', (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<html lang="en">
- <head>
- <title>my_${req.path.slice(1)}</title>
- </head>
- <body><h1>${req.path}</h1></body>
-</html">`);
- });
- return app;
-};
-
-describe('quit/quitall command test', () => {
- const port = 12321;
- let http;
- let firefox;
- let session;
- let browser;
-
- before(async() => {
- http = newApp().listen(port);
-
- firefox = await lanthan.firefox({
- spy: path.join(__dirname, '..'),
- builderf: (builder) => {
- builder.addFile('build/settings.js');
- },
- });
- session = firefox.session;
- browser = firefox.browser;
- });
-
- after(async() => {
- http.close();
- if (firefox) {
- await firefox.close();
- }
- });
-
- beforeEach(async() => {
- let tabs = await browser.tabs.query({});
- for (let tab of tabs.slice(1)) {
- await browser.tabs.remove(tab.id);
- }
- await browser.tabs.update(tabs[0].id, { url: `http://127.0.0.1:${port}/site1` });
- for (let i = 2; i <= 5; ++i) {
- await browser.tabs.create({ url: `http://127.0.0.1:${port}/site${i}`})
- }
-
- await eventually(async() => {
- let handles = await session.getWindowHandles();
- assert.equal(handles.length, 5);
- await session.switchToWindow(handles[2]);
- await session.findElementByCSS('iframe');
- });
-
- await new Promise((resolve) => setTimeout(resolve, 100));
- });
-
- it('should current tab by q command', async() => {
- let body = await session.findElementByCSS('body');
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- await input.sendKeys('q', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({});
- assert.equal(tabs.length, 4)
- });
- });
-
- it('should current tab by quit command', async() => {
- let body = await session.findElementByCSS('body');
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- await input.sendKeys('quit', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({});
- assert.equal(tabs.length, 4)
- });
- });
-
- it('should current tab by qa command', async() => {
- let body = await session.findElementByCSS('body');
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- await input.sendKeys('qa', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({});
- assert.equal(tabs.length, 1)
- });
- });
-
- it('should current tab by quitall command', async() => {
- let body = await session.findElementByCSS('body');
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- await input.sendKeys('quitall', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({});
- assert.equal(tabs.length, 1)
- });
- });
-});
diff --git a/e2e/command_quit.test.ts b/e2e/command_quit.test.ts
new file mode 100644
index 0000000..239d880
--- /dev/null
+++ b/e2e/command_quit.test.ts
@@ -0,0 +1,93 @@
+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 } from 'selenium-webdriver';
+import Page from './lib/Page';
+
+describe('quit/quitall command test', () => {
+ let server = new TestServer().receiveContent('/*', 'ok');
+ 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();
+ }
+ });
+
+ beforeEach(async() => {
+ let tabs = await browser.tabs.query({});
+ for (let tab of tabs.slice(1)) {
+ await browser.tabs.remove(tab.id);
+ }
+ await browser.tabs.update(tabs[0].id, { url: server.url('/site1') });
+ for (let i = 2; i <= 5; ++i) {
+ await browser.tabs.create({ url: server.url('/site' + i) })
+ }
+
+ await eventually(async() => {
+ let handles = await webdriver.getAllWindowHandles();
+ assert.strictEqual(handles.length, 5);
+ await webdriver.switchTo().window(handles[2]);
+ });
+ });
+
+ it('should current tab by q command', async() => {
+ let page = await Page.currentContext(webdriver);
+ let console = await page.showConsole();
+ await console.execCommand('q');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({});
+ assert.strictEqual(tabs.length, 4)
+ });
+ });
+
+ it('should current tab by quit command', async() => {
+ let page = await Page.currentContext(webdriver);
+ let console = await page.showConsole();
+ await console.execCommand('quit');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({});
+ assert.strictEqual(tabs.length, 4)
+ });
+ });
+
+ it('should current tab by qa command', async() => {
+ let page = await Page.currentContext(webdriver);
+ let console = await page.showConsole();
+ await console.execCommand('qa');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({});
+ assert.strictEqual(tabs.length, 1)
+ });
+ });
+
+ it('should current tab by quitall command', async() => {
+ let page = await Page.currentContext(webdriver);
+ let console = await page.showConsole();
+ await console.execCommand('quitall');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({});
+ assert.strictEqual(tabs.length, 1)
+ });
+ });
+});
diff --git a/e2e/command_tabopen.test.js b/e2e/command_tabopen.test.js
deleted file mode 100644
index 9c5cf3a..0000000
--- a/e2e/command_tabopen.test.js
+++ /dev/null
@@ -1,160 +0,0 @@
-const express = require('express');
-const lanthan = require('lanthan');
-const path = require('path');
-const assert = require('assert');
-const eventually = require('./eventually');
-const settings = require('./settings');
-
-const Key = lanthan.Key;
-
-const newApp = () => {
-
- let app = express();
- for (let name of ['google', 'yahoo', 'bing', 'duckduckgo', 'twitter', 'wikipedia']) {
- app.get('/' + name, (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<html lang="en">
- <body><h1>${name.charAt(0).toUpperCase() + name.slice(1)}</h1></body>
-</html">`);
- });
- }
- app.get('/', (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<html lang="en">
- <body><h1>home</h1></body>
-</html">`);
- });
- return app;
-};
-
-describe("tabopen command test", () => {
- const port = 12321;
- let http;
- let firefox;
- let session;
- let browser;
- let body;
-
- before(async() => {
- http = newApp().listen(port);
-
- firefox = await lanthan.firefox({
- spy: path.join(__dirname, '..'),
- builderf: (builder) => {
- builder.addFile('build/settings.js');
- },
- });
- session = firefox.session;
- browser = firefox.browser;
- await browser.storage.local.set({
- settings,
- });
- });
-
- after(async() => {
- http.close();
- if (firefox) {
- await firefox.close();
- }
- });
-
- beforeEach(async() => {
- let tabs = await browser.tabs.query({});
- for (let tab of tabs.slice(1)) {
- await browser.tabs.remove(tab.id);
- }
-
- await session.navigateTo(`http://127.0.0.1:${port}`);
- body = await session.findElementByCSS('body');
- })
-
- it('should open default search for keywords by tabopen command ', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- input.sendKeys('tabopen an apple', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({});
- assert.equal(tabs.length, 2);
- let url = new URL(tabs[1].url);
- assert.equal(url.href, `http://127.0.0.1:${port}/google?q=an%20apple`)
- });
- });
-
- it('should open certain search page for keywords by tabopen command ', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- input.sendKeys('tabopen yahoo an apple', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({});
- assert.equal(tabs.length, 2);
- let url = new URL(tabs[1].url);
- assert.equal(url.href, `http://127.0.0.1:${port}/yahoo?q=an%20apple`)
- });
- });
-
- it('should open default engine with empty keywords by tabopen command ', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- input.sendKeys('tabopen', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({});
- assert.equal(tabs.length, 2);
- let url = new URL(tabs[1].url);
- assert.equal(url.href, `http://127.0.0.1:${port}/google?q=`)
- });
- });
-
- it('should open certain search page for empty keywords by tabopen command ', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- input.sendKeys('tabopen yahoo', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({});
- assert.equal(tabs.length, 2);
- let url = new URL(tabs[1].url);
- assert.equal(url.href, `http://127.0.0.1:${port}/yahoo?q=`)
- });
- });
-
- it('should open a site with domain by tabopen command ', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- input.sendKeys('tabopen i-beam.org', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({});
- assert.equal(tabs.length, 2);
- let url = new URL(tabs[1].url);
- assert.equal(url.href, 'https://i-beam.org/')
- });
- });
-
- it('should open a site with URL by tabopen command ', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- input.sendKeys('tabopen https://i-beam.org', Key.Enter);
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({});
- assert.equal(tabs.length, 2);
- let url = new URL(tabs[1].url);
- assert.equal(url.href, 'https://i-beam.org/')
- });
- });
-});
diff --git a/e2e/command_tabopen.test.ts b/e2e/command_tabopen.test.ts
new file mode 100644
index 0000000..9d3da9a
--- /dev/null
+++ b/e2e/command_tabopen.test.ts
@@ -0,0 +1,122 @@
+import * as path from 'path';
+import * as assert from 'assert';
+
+import TestServer from './lib/TestServer';
+import settings from './settings';
+import eventually from './eventually';
+import { Builder, Lanthan } from 'lanthan';
+import { WebDriver } from 'selenium-webdriver';
+import Page from './lib/Page';
+
+describe("tabopen command test", () => {
+ let server = new TestServer(12321)
+ .receiveContent('/google', 'google')
+ .receiveContent('/yahoo', 'yahoo');
+ let lanthan: Lanthan;
+ let webdriver: WebDriver;
+ let browser: any;
+ let page: Page;
+
+ before(async() => {
+ lanthan = await Builder
+ .forBrowser('firefox')
+ .spyAddon(path.join(__dirname, '..'))
+ .build();
+ webdriver = lanthan.getWebDriver();
+ browser = lanthan.getWebExtBrowser();
+
+ await browser.storage.local.set({
+ settings,
+ });
+
+ await server.start();
+ });
+
+ after(async() => {
+ await server.stop();
+ if (lanthan) {
+ await lanthan.quit();
+ }
+ });
+
+ beforeEach(async() => {
+ let tabs = await browser.tabs.query({});
+ for (let tab of tabs.slice(1)) {
+ await browser.tabs.remove(tab.id);
+ }
+
+ page = await Page.navigateTo(webdriver, server.url());
+ })
+
+ it('should open default search for keywords by tabopen command ', async() => {
+ let console = await page.showConsole();
+ await console.execCommand('tabopen an apple');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({});
+ assert.strictEqual(tabs.length, 2);
+ let url = new URL(tabs[1].url);
+ assert.strictEqual(url.href, server.url('/google?q=an%20apple') )
+ });
+ });
+
+ it('should open certain search page for keywords by tabopen command ', async() => {
+ let console = await page.showConsole();
+ await console.execCommand('tabopen yahoo an apple');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({});
+ assert.strictEqual(tabs.length, 2);
+ let url = new URL(tabs[1].url);
+ assert.strictEqual(url.href, server.url('/yahoo?q=an%20apple'))
+ });
+ });
+
+ it('should open default engine with empty keywords by tabopen command ', async() => {
+ let console = await page.showConsole();
+ await console.execCommand('tabopen');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({});
+ assert.strictEqual(tabs.length, 2);
+ let url = new URL(tabs[1].url);
+ assert.strictEqual(url.href, server.url('/google?q='))
+ });
+ });
+
+ it('should open certain search page for empty keywords by tabopen command ', async() => {
+ let console = await page.showConsole();
+ await console.execCommand('tabopen yahoo');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({});
+ assert.strictEqual(tabs.length, 2);
+ let url = new URL(tabs[1].url);
+ assert.strictEqual(url.href, server.url('/yahoo?q='))
+ });
+ });
+
+ it('should open a site with domain by tabopen command ', async() => {
+ let console = await page.showConsole();
+ await console.execCommand('tabopen example.com');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({});
+ assert.strictEqual(tabs.length, 2);
+ let url = new URL(tabs[1].url);
+ assert.strictEqual(url.href, 'http://example.com/')
+ });
+ });
+
+ it('should open a site with URL by tabopen command ', async() => {
+ let console = await page.showConsole();
+ await console.execCommand('tabopen https://example.com/');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({});
+ assert.strictEqual(tabs.length, 2);
+ let url = new URL(tabs[1].url);
+ assert.strictEqual(url.href, 'https://example.com/')
+ });
+ });
+});
diff --git a/e2e/command_winopen.test.js b/e2e/command_winopen.test.js
deleted file mode 100644
index 536d759..0000000
--- a/e2e/command_winopen.test.js
+++ /dev/null
@@ -1,172 +0,0 @@
-const express = require('express');
-const lanthan = require('lanthan');
-const path = require('path');
-const assert = require('assert');
-const eventually = require('./eventually');
-const settings = require('./settings');
-
-const Key = lanthan.Key;
-
-const newApp = () => {
-
- let app = express();
- for (let name of ['google', 'yahoo', 'bing', 'duckduckgo', 'twitter', 'wikipedia']) {
- app.get('/' + name, (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<html lang="en">
- <body><h1>${name.charAt(0).toUpperCase() + name.slice(1)}</h1></body>
-</html">`);
- });
- }
- app.get('/', (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<html lang="en">
- <body><h1>home</h1></body>
-</html">`);
- });
- return app;
-};
-
-describe("winopen command test", () => {
- const port = 12321;
- let http;
- let firefox;
- let session;
- let browser;
- let body;
-
- before(async() => {
- http = newApp().listen(port);
-
- firefox = await lanthan.firefox({
- spy: path.join(__dirname, '..'),
- builderf: (builder) => {
- builder.addFile('build/settings.js');
- },
- });
- session = firefox.session;
- browser = firefox.browser;
- await browser.storage.local.set({
- settings,
- });
- });
-
- after(async() => {
- http.close();
- if (firefox) {
- await firefox.close();
- }
- });
-
- beforeEach(async() => {
- let wins = await browser.windows.getAll();
- for (let win of wins.slice(1)) {
- await browser.windows.remove(win.id);
- }
-
- await session.navigateTo(`http://127.0.0.1:${port}`);
- body = await session.findElementByCSS('body');
- })
-
- it('should open default search for keywords by winopen command ', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- input.sendKeys('winopen an apple', Key.Enter);
-
- await eventually(async() => {
- let wins = await browser.windows.getAll();
- assert.equal(wins.length, 2);
-
- let tabs = await browser.tabs.query({ windowId: wins[1].id });
- let url = new URL(tabs[0].url);
- assert.equal(url.href, `http://127.0.0.1:${port}/google?q=an%20apple`)
- });
- });
-
- it('should open certain search page for keywords by winopen command ', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- input.sendKeys('winopen yahoo an apple', Key.Enter);
-
- await eventually(async() => {
- let wins = await browser.windows.getAll();
- assert.equal(wins.length, 2);
-
- let tabs = await browser.tabs.query({ windowId: wins[1].id });
- let url = new URL(tabs[0].url);
- assert.equal(url.href, `http://127.0.0.1:${port}/yahoo?q=an%20apple`)
- });
- });
-
- it('should open default engine with empty keywords by winopen command ', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- input.sendKeys('winopen', Key.Enter);
-
- await eventually(async() => {
- let wins = await browser.windows.getAll();
- assert.equal(wins.length, 2);
-
- let tabs = await browser.tabs.query({ windowId: wins[1].id });
- let url = new URL(tabs[0].url);
- assert.equal(url.href, `http://127.0.0.1:${port}/google?q=`)
- });
- });
-
- it('should open certain search page for empty keywords by winopen command ', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- input.sendKeys('winopen yahoo', Key.Enter);
-
- await eventually(async() => {
- let wins = await browser.windows.getAll();
- assert.equal(wins.length, 2);
-
- let tabs = await browser.tabs.query({ windowId: wins[1].id });
- let url = new URL(tabs[0].url);
- assert.equal(url.href, `http://127.0.0.1:${port}/yahoo?q=`)
- });
- });
-
- it('should open a site with domain by winopen command ', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- input.sendKeys('winopen i-beam.org', Key.Enter);
-
- await eventually(async() => {
- let wins = await browser.windows.getAll();
- assert.equal(wins.length, 2);
-
- let tabs = await browser.tabs.query({ windowId: wins[1].id });
- let url = new URL(tabs[0].url);
- assert.equal(url.href, 'https://i-beam.org/')
- });
- });
-
- it('should open a site with URL by winopen command ', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- input.sendKeys('winopen https://i-beam.org', Key.Enter);
-
- await eventually(async() => {
- let wins = await browser.windows.getAll();
- assert.equal(wins.length, 2);
-
- let tabs = await browser.tabs.query({ windowId: wins[1].id });
- let url = new URL(tabs[0].url);
- assert.equal(url.href, 'https://i-beam.org/')
- });
- });
-});
diff --git a/e2e/command_winopen.test.ts b/e2e/command_winopen.test.ts
new file mode 100644
index 0000000..95a0b6a
--- /dev/null
+++ b/e2e/command_winopen.test.ts
@@ -0,0 +1,133 @@
+import * as path from 'path';
+import * as assert from 'assert';
+
+import TestServer from './lib/TestServer';
+import settings from './settings';
+import eventually from './eventually';
+import { Builder, Lanthan } from 'lanthan';
+import { WebDriver } from 'selenium-webdriver';
+import Page from './lib/Page';
+
+describe("winopen command test", () => {
+ let server = new TestServer(12321)
+ .receiveContent('/google', 'google')
+ .receiveContent('/yahoo', 'yahoo');
+ let lanthan: Lanthan;
+ let webdriver: WebDriver;
+ let browser: any;
+ let page: Page;
+
+ before(async() => {
+ lanthan = await Builder
+ .forBrowser('firefox')
+ .spyAddon(path.join(__dirname, '..'))
+ .build();
+ webdriver = lanthan.getWebDriver();
+ browser = lanthan.getWebExtBrowser();
+ await browser.storage.local.set({
+ settings,
+ });
+
+ await server.start();
+ });
+
+ after(async() => {
+ await server.stop();
+ if (lanthan) {
+ await lanthan.quit();
+ }
+ });
+
+ beforeEach(async() => {
+ let wins = await browser.windows.getAll();
+ for (let win of wins.slice(1)) {
+ await browser.windows.remove(win.id);
+ }
+
+ page = await Page.navigateTo(webdriver, server.url());
+ })
+
+ it('should open default search for keywords by winopen command ', async() => {
+ let console = await page.showConsole();
+ await console.execCommand('winopen an apple');
+
+ await eventually(async() => {
+ let wins = await browser.windows.getAll();
+ assert.strictEqual(wins.length, 2);
+
+ let tabs = await browser.tabs.query({ windowId: wins[1].id });
+ let url = new URL(tabs[0].url);
+ assert.strictEqual(url.href, server.url('/google?q=an%20apple'))
+ });
+ });
+
+ it('should open certain search page for keywords by winopen command ', async() => {
+ let console = await page.showConsole();
+ await console.execCommand('winopen yahoo an apple');
+
+ await eventually(async() => {
+ let wins = await browser.windows.getAll();
+ assert.strictEqual(wins.length, 2);
+
+ let tabs = await browser.tabs.query({ windowId: wins[1].id });
+ let url = new URL(tabs[0].url);
+ assert.strictEqual(url.href, server.url('/yahoo?q=an%20apple'))
+ });
+ });
+
+ it('should open default engine with empty keywords by winopen command ', async() => {
+ let console = await page.showConsole();
+ await console.execCommand('winopen');
+
+ await eventually(async() => {
+ let wins = await browser.windows.getAll();
+ assert.strictEqual(wins.length, 2);
+
+ let tabs = await browser.tabs.query({ windowId: wins[1].id });
+ let url = new URL(tabs[0].url);
+ assert.strictEqual(url.href, server.url('/google?q='))
+ });
+ });
+
+ it('should open certain search page for empty keywords by winopen command ', async() => {
+ let console = await page.showConsole();
+ await console.execCommand('winopen yahoo');
+
+ await eventually(async() => {
+ let wins = await browser.windows.getAll();
+ assert.strictEqual(wins.length, 2);
+
+ let tabs = await browser.tabs.query({ windowId: wins[1].id });
+ let url = new URL(tabs[0].url);
+ assert.strictEqual(url.href, server.url('/yahoo?q='))
+ });
+ });
+
+ it('should open a site with domain by winopen command ', async() => {
+ let console = await page.showConsole();
+ await console.execCommand('winopen example.com');
+
+ await eventually(async() => {
+ let wins = await browser.windows.getAll();
+ assert.strictEqual(wins.length, 2);
+
+ let tabs = await browser.tabs.query({ windowId: wins[1].id });
+ let url = new URL(tabs[0].url);
+ assert.strictEqual(url.href, 'http://example.com/')
+ });
+ });
+
+ it('should open a site with URL by winopen command ', async() => {
+ let console = await page.showConsole();
+ await console.execCommand('winopen https://example.com/');
+
+ await eventually(async() => {
+ let wins = await browser.windows.getAll();
+ assert.strictEqual(wins.length, 2);
+
+ let tabs = await browser.tabs.query({ windowId: wins[1].id });
+ let url = new URL(tabs[0].url);
+ assert.strictEqual(url.href, 'https://example.com/')
+ });
+ });
+});
diff --git a/e2e/completion.test.js b/e2e/completion.test.js
deleted file mode 100644
index 5d910c6..0000000
--- a/e2e/completion.test.js
+++ /dev/null
@@ -1,136 +0,0 @@
-const express = require('express');
-const lanthan = require('lanthan');
-const path = require('path');
-const assert = require('assert');
-const eventually = require('./eventually');
-const settings = require('./settings');
-const Console = require('./lib/Console');
-
-const Key = lanthan.Key;
-
-const newApp = () => {
- let app = express();
- app.get('/', (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<html lang="en">
- <body>ok</body>
-</html">`);
- });
- return app;
-};
-
-describe("general completion test", () => {
- const port = 12321;
- let http;
- let firefox;
- let session;
- let browser;
- let body;
-
- before(async() => {
- firefox = await lanthan.firefox({
- spy: path.join(__dirname, '..'),
- builderf: (builder) => {
- builder.addFile('build/settings.js');
- },
- });
- session = firefox.session;
- browser = firefox.browser;
- http = newApp().listen(port);
-
- await browser.storage.local.set({
- settings,
- });
- });
-
- after(async() => {
- http.close();
- if (firefox) {
- await firefox.close();
- }
- });
-
- beforeEach(async() => {
- await session.navigateTo(`http://127.0.0.1:${port}`);
- body = await session.findElementByCSS('body');
- });
-
- it('should all commands on empty line', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let c = new Console(session);
-
- await eventually(async() => {
- let items = await c.getCompletions();
- assert.equal(items.length, 10);
- assert.deepEqual(items[0], { type: 'title', text: 'Console Command' });
- assert(items[1].text.startsWith('set'))
- assert(items[2].text.startsWith('open'))
- assert(items[3].text.startsWith('tabopen'))
- });
- });
-
- it('should only commands filtered by prefix', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let c = new Console(session);
- await c.sendKeys('b');
-
- await eventually(async() => {
- let items = await c.getCompletions();
- assert.equal(items.length, 4);
- assert.deepEqual(items[0], { type: 'title', text: 'Console Command' });
- assert(items[1].text.startsWith('buffer'))
- assert(items[2].text.startsWith('bdelete'))
- assert(items[3].text.startsWith('bdeletes'))
- });
- });
-
- it('selects completion items by <Tab>/<S-Tab> keys', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let c = new Console(session);
- await c.sendKeys('b');
-
- await eventually(async() => {
- let items = await c.getCompletions();
- assert.equal(items.length, 4);
- });
-
- await c.sendKeys(Key.Tab);
- await eventually(async() => {
- let items = await c.getCompletions();
- assert(items[1].highlight)
-
- let v = await c.currentValue();
- assert.equal(v, 'buffer');
- });
-
- await c.sendKeys(Key.Tab, Key.Tab);
- await eventually(async() => {
- let items = await c.getCompletions();
- assert(items[3].highlight)
-
- let v = await c.currentValue();
- assert.equal(v, 'bdeletes');
- });
-
- await c.sendKeys(Key.Tab);
- await eventually(async() => {
- let v = await c.currentValue();
- assert.equal(v, 'b');
- });
-
- await c.sendKeys(Key.Shift, Key.Tab);
- await eventually(async() => {
- let items = await c.getCompletions();
- assert(items[3].highlight)
-
- let v = await c.currentValue();
- assert.equal(v, 'bdeletes');
- });
- });
-});
diff --git a/e2e/completion.test.ts b/e2e/completion.test.ts
new file mode 100644
index 0000000..28c1913
--- /dev/null
+++ b/e2e/completion.test.ts
@@ -0,0 +1,100 @@
+import * as path from 'path';
+import * as assert from 'assert';
+
+import eventually from './eventually';
+import settings from './settings';
+import { Builder, Lanthan } from 'lanthan';
+import { WebDriver, Key } from 'selenium-webdriver';
+import Page from './lib/Page';
+
+describe("general completion test", () => {
+ let lanthan: Lanthan;
+ let webdriver: WebDriver;
+ let browser: any;
+ let page: Page;
+
+ before(async() => {
+ lanthan = await Builder
+ .forBrowser('firefox')
+ .spyAddon(path.join(__dirname, '..'))
+ .build();
+ webdriver = lanthan.getWebDriver();
+ browser = lanthan.getWebExtBrowser();
+
+ await browser.storage.local.set({
+ settings,
+ });
+ });
+
+ after(async() => {
+ if (lanthan) {
+ await lanthan.quit();
+ }
+ });
+
+ beforeEach(async() => {
+ page = await Page.navigateTo(webdriver, 'about:blank');
+ });
+
+ it('should all commands on empty line', async() => {
+ let console = await page.showConsole();
+
+ let items = await console.getCompletions();
+ assert.strictEqual(items.length, 10);
+ assert.deepStrictEqual(items[0], { type: 'title', text: 'Console Command' });
+ assert.ok(items[1].text.startsWith('set'))
+ assert.ok(items[2].text.startsWith('open'))
+ assert.ok(items[3].text.startsWith('tabopen'))
+ });
+
+ it('should only commands filtered by prefix', async() => {
+ let console = await page.showConsole();
+ await console.inputKeys('b');
+
+ let items = await console.getCompletions();
+ assert.strictEqual(items.length, 4);
+ assert.deepStrictEqual(items[0], { type: 'title', text: 'Console Command' });
+ assert.ok(items[1].text.startsWith('buffer'))
+ assert.ok(items[2].text.startsWith('bdelete'))
+ assert.ok(items[3].text.startsWith('bdeletes'))
+ });
+
+ // > byffer
+ // > bdelete
+ // > bdeletes
+ // : b
+ it('selects completion items by <Tab>/<S-Tab> keys', async() => {
+ let console = await page.showConsole();
+ await console.inputKeys('b');
+ await eventually(async() => {
+ let items = await console.getCompletions();
+ assert.strictEqual(items.length, 4);
+ });
+
+ await console.sendKeys(Key.TAB);
+ await eventually(async() => {
+ let items = await console.getCompletions();
+ assert.ok(items[1].highlight)
+ assert.strictEqual(await console.currentValue(), 'buffer');
+ });
+
+ await console.sendKeys(Key.TAB, Key.TAB);
+ await eventually(async() => {
+ let items = await console.getCompletions();
+ assert.ok(items[3].highlight)
+ assert.strictEqual(await console.currentValue(), 'bdeletes');
+ });
+
+ await console.sendKeys(Key.TAB);
+ await eventually(async() => {
+ assert.strictEqual(await console.currentValue(), 'b');
+ });
+
+ await console.sendKeys(Key.SHIFT, Key.TAB);
+ await eventually(async() => {
+ let items = await console.getCompletions();
+ assert.ok(items[3].highlight)
+ assert.strictEqual(await console.currentValue(), 'bdeletes');
+ });
+ });
+});
diff --git a/e2e/completion_buffers.test.js b/e2e/completion_buffers.test.js
deleted file mode 100644
index de26747..0000000
--- a/e2e/completion_buffers.test.js
+++ /dev/null
@@ -1,214 +0,0 @@
-const express = require('express');
-const lanthan = require('lanthan');
-const path = require('path');
-const assert = require('assert');
-const eventually = require('./eventually');
-const settings = require('./settings');
-const Console = require('./lib/Console');
-
-const Key = lanthan.Key;
-
-const newApp = () => {
-
- let app = express();
- app.get('/*', (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<html lang="en">
- <head>
- <title>title_${req.path.slice(1)}</title>
- </head>
- <body><h1>home</h1></body>
-</html">`);
- });
- return app;
-};
-
-describe("completion on buffer/bdelete/bdeletes", () => {
- const port = 12321;
- let http;
- let firefox;
- let session;
- let browser;
- let body;
-
- before(async() => {
- firefox = await lanthan.firefox({
- spy: path.join(__dirname, '..'),
- builderf: (builder) => {
- builder.addFile('build/settings.js');
- },
- });
- session = firefox.session;
- browser = firefox.browser;
- http = newApp().listen(port);
-
- await browser.storage.local.set({
- settings,
- });
- });
-
- after(async() => {
- http.close();
- if (firefox) {
- await firefox.close();
- }
- });
-
- beforeEach(async() => {
- let tabs = await browser.tabs.query({});
- for (let tab of tabs.slice(1)) {
- await browser.tabs.remove(tab.id);
- }
-
- await browser.tabs.update(tabs[0].id, { url: `http://127.0.0.1:${port}/site1`, pinned: true });
- await browser.tabs.create({ url: `http://127.0.0.1:${port}/site2`, pinned: true })
- for (let i = 3; i <= 5; ++i) {
- await browser.tabs.create({ url: `http://127.0.0.1:${port}/site${i}` })
- }
-
- await eventually(async() => {
- let handles = await session.getWindowHandles();
- assert.equal(handles.length, 5);
- await session.switchToWindow(handles[2]);
- await session.findElementByCSS('iframe');
- });
- body = await session.findElementByCSS('body');
-
- await new Promise((resolve) => setTimeout(resolve, 100));
- });
-
- it('should all tabs by "buffer" command with empty params', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let c = new Console(session);
- await c.sendKeys('buffer ');
-
- await eventually(async() => {
- let items = await c.getCompletions();
- assert.equal(items.length, 6);
- assert.deepEqual(items[0], { type: 'title', text: 'Buffers' });
- assert(items[1].text.startsWith('1:'));
- assert(items[2].text.startsWith('2:'));
- assert(items[3].text.startsWith('3:'));
- assert(items[4].text.startsWith('4:'));
- assert(items[5].text.startsWith('5:'));
-
- assert(items[3].text.includes('%'));
- assert(items[5].text.includes('#'));
- });
- })
-
- it('should filter items with URLs by keywords on "buffer" command', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let c = new Console(session);
- await c.sendKeys('buffer title_site2');
-
- await eventually(async() => {
- let items = await c.getCompletions();
- assert.deepEqual(items[0], { type: 'title', text: 'Buffers' });
- assert(items[1].text.startsWith('2:'));
- assert(items[1].text.includes('title_site2'));
- assert(items[1].text.includes(`http://127.0.0.1:${port}/site2`));
- });
- })
-
- it('should filter items with titles by keywords on "buffer" command', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let c = new Console(session);
- await c.sendKeys('buffer /site2');
-
- await eventually(async() => {
- let items = await c.getCompletions();
- assert.deepEqual(items[0], { type: 'title', text: 'Buffers' });
- assert(items[1].text.startsWith('2:'));
- });
- })
-
- it('should show one item by number on "buffer" command', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let c = new Console(session);
- await c.sendKeys('buffer 2');
-
- await eventually(async() => {
- let items = await c.getCompletions();
- assert.equal(items.length, 2);
- assert.deepEqual(items[0], { type: 'title', text: 'Buffers' });
- assert(items[1].text.startsWith('2:'));
- });
- })
-
- it('should show unpinned tabs "bdelete" command', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let c = new Console(session);
- await c.sendKeys('bdelete site');
-
- await eventually(async() => {
- let items = await c.getCompletions();
- assert.equal(items.length, 4);
- assert(items[1].text.includes('site3'));
- assert(items[2].text.includes('site4'));
- assert(items[3].text.includes('site5'));
- });
- })
-
- it('should show unpinned tabs "bdeletes" command', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let c = new Console(session);
- await c.sendKeys('bdelete site');
-
- await eventually(async() => {
- let items = await c.getCompletions();
- assert.equal(items.length, 4);
- assert(items[1].text.includes('site3'));
- assert(items[2].text.includes('site4'));
- assert(items[3].text.includes('site5'));
- });
- })
-
- it('should show both pinned and unpinned tabs "bdelete!" command', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let c = new Console(session);
- await c.sendKeys('bdelete! site');
-
- await eventually(async() => {
- let items = await c.getCompletions();
- assert.equal(items.length, 6);
- assert(items[1].text.includes('site1'));
- assert(items[2].text.includes('site2'));
- assert(items[3].text.includes('site3'));
- assert(items[4].text.includes('site4'));
- assert(items[5].text.includes('site5'));
- });
- })
-
- it('should show both pinned and unpinned tabs "bdeletes!" command', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let c = new Console(session);
- await c.sendKeys('bdeletes! site');
-
- await eventually(async() => {
- let items = await c.getCompletions();
- assert.equal(items.length, 6);
- assert(items[1].text.includes('site1'));
- assert(items[2].text.includes('site2'));
- assert(items[3].text.includes('site3'));
- assert(items[4].text.includes('site4'));
- assert(items[5].text.includes('site5'));
- });
- })
-});
diff --git a/e2e/completion_buffers.test.ts b/e2e/completion_buffers.test.ts
new file mode 100644
index 0000000..b2d4201
--- /dev/null
+++ b/e2e/completion_buffers.test.ts
@@ -0,0 +1,180 @@
+import * as assert from 'assert';
+import * as path from 'path';
+
+import { Request, Response } from 'express'
+import TestServer from './lib/TestServer';
+import settings from './settings';
+import eventually from './eventually';
+import { Builder, Lanthan } from 'lanthan';
+import { WebDriver } from 'selenium-webdriver';
+import Page from './lib/Page';
+
+describe("completion on buffer/bdelete/bdeletes", () => {
+ let server = new TestServer().handle('/*', (req: Request, res: Response) => {
+ res.send(`
+ <!DOCTYPE html>
+ <html lang="en">
+ <head>
+ <title>title_${req.path.slice(1)}</title>
+ </head>
+ </html">`);
+ });
+ let lanthan: Lanthan;
+ let webdriver: WebDriver;
+ let browser: any;
+ let page: Page;
+
+ before(async() => {
+ lanthan = await Builder
+ .forBrowser('firefox')
+ .spyAddon(path.join(__dirname, '..'))
+ .build();
+ webdriver = lanthan.getWebDriver();
+ browser = lanthan.getWebExtBrowser();
+
+ await browser.storage.local.set({
+ settings,
+ });
+
+ await server.start();
+ });
+
+ after(async() => {
+ await server.stop();
+ if (lanthan) {
+ await lanthan.quit();
+ }
+ });
+
+ beforeEach(async() => {
+ let tabs = await browser.tabs.query({});
+ for (let tab of tabs.slice(1)) {
+ await browser.tabs.remove(tab.id);
+ }
+
+ await browser.tabs.update(tabs[0].id, { url: server.url('/site1'), pinned: true });
+ await browser.tabs.create({ url:server.url('/site2'), pinned: true })
+ for (let i = 3; i <= 5; ++i) {
+ await browser.tabs.create({ url: server.url('/site' + i) });
+ }
+
+ await eventually(async() => {
+ let handles = await webdriver.getAllWindowHandles();
+ assert.strictEqual(handles.length, 5);
+ await webdriver.switchTo().window(handles[2]);
+ });
+
+ page = await Page.currentContext(webdriver);
+ });
+
+ it('should all tabs by "buffer" command with empty params', async() => {
+ let console = await page.showConsole();
+ await console.inputKeys('buffer ');
+
+ await eventually(async() => {
+ let items = await console.getCompletions();
+ assert.strictEqual(items.length, 6);
+ assert.deepStrictEqual(items[0], { type: 'title', text: 'Buffers' });
+ assert.ok(items[1].text.startsWith('1:'));
+ assert.ok(items[2].text.startsWith('2:'));
+ assert.ok(items[3].text.startsWith('3:'));
+ assert.ok(items[4].text.startsWith('4:'));
+ assert.ok(items[5].text.startsWith('5:'));
+
+ assert.ok(items[3].text.includes('%'));
+ assert.ok(items[5].text.includes('#'));
+ });
+ })
+
+ it('should filter items with URLs by keywords on "buffer" command', async() => {
+ let console = await page.showConsole();
+ await console.inputKeys('buffer title_site2');
+
+ await eventually(async() => {
+ let items = await console.getCompletions();
+ assert.deepStrictEqual(items[0], { type: 'title', text: 'Buffers' });
+ assert.ok(items[1].text.startsWith('2:'));
+ assert.ok(items[1].text.includes('title_site2'));
+ assert.ok(items[1].text.includes(server.url('/site2')));
+ });
+ })
+
+ it('should filter items with titles by keywords on "buffer" command', async() => {
+ let console = await page.showConsole();
+ await console.inputKeys('buffer /site2');
+
+ await eventually(async() => {
+ let items = await console.getCompletions();
+ assert.deepStrictEqual(items[0], { type: 'title', text: 'Buffers' });
+ assert.ok(items[1].text.startsWith('2:'));
+ });
+ })
+
+ it('should show one item by number on "buffer" command', async() => {
+ let console = await page.showConsole();
+ await console.inputKeys('buffer 2');
+
+ await eventually(async() => {
+ let items = await console.getCompletions();
+ assert.strictEqual(items.length, 2);
+ assert.deepStrictEqual(items[0], { type: 'title', text: 'Buffers' });
+ assert.ok(items[1].text.startsWith('2:'));
+ });
+ })
+
+ it('should show unpinned tabs "bdelete" command', async() => {
+ let console = await page.showConsole();
+ await console.inputKeys('bdelete site');
+
+ await eventually(async() => {
+ let items = await console.getCompletions();
+ assert.strictEqual(items.length, 4);
+ assert.ok(items[1].text.includes('site3'));
+ assert.ok(items[2].text.includes('site4'));
+ assert.ok(items[3].text.includes('site5'));
+ });
+ })
+
+ it('should show unpinned tabs "bdeletes" command', async() => {
+ let console = await page.showConsole();
+ await console.inputKeys('bdeletes site');
+
+ await eventually(async() => {
+ let items = await console.getCompletions();
+ assert.strictEqual(items.length, 4);
+ assert.ok(items[1].text.includes('site3'));
+ assert.ok(items[2].text.includes('site4'));
+ assert.ok(items[3].text.includes('site5'));
+ });
+ })
+
+ it('should show both pinned and unpinned tabs "bdelete!" command', async() => {
+ let console = await page.showConsole();
+ await console.inputKeys('bdelete! site');
+
+ await eventually(async() => {
+ let items = await console.getCompletions();
+ assert.strictEqual(items.length, 6);
+ assert.ok(items[1].text.includes('site1'));
+ assert.ok(items[2].text.includes('site2'));
+ assert.ok(items[3].text.includes('site3'));
+ assert.ok(items[4].text.includes('site4'));
+ assert.ok(items[5].text.includes('site5'));
+ });
+ })
+
+ it('should show both pinned and unpinned tabs "bdeletes!" command', async() => {
+ let console = await page.showConsole();
+ await console.inputKeys('bdeletes! site');
+
+ await eventually(async() => {
+ let items = await console.getCompletions();
+ assert.strictEqual(items.length, 6);
+ assert.ok(items[1].text.includes('site1'));
+ assert.ok(items[2].text.includes('site2'));
+ assert.ok(items[3].text.includes('site3'));
+ assert.ok(items[4].text.includes('site4'));
+ assert.ok(items[5].text.includes('site5'));
+ });
+ })
+});
diff --git a/e2e/completion_open.test.js b/e2e/completion_open.test.js
deleted file mode 100644
index 5828768..0000000
--- a/e2e/completion_open.test.js
+++ /dev/null
@@ -1,255 +0,0 @@
-const express = require('express');
-const lanthan = require('lanthan');
-const path = require('path');
-const assert = require('assert');
-const eventually = require('./eventually');
-const settings = require('./settings');
-const Console = require('./lib/Console');
-
-const Key = lanthan.Key;
-
-const newApp = () => {
-
- let app = express();
- app.get('/', (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<html lang="en">
- <body>ok</body>
-</html">`);
- });
- return app;
-};
-
-describe("completion on open/tabopen/winopen commands", () => {
- const port = 12321;
- let http;
- let firefox;
- let session;
- let browser;
- let body;
-
- before(async() => {
- firefox = await lanthan.firefox({
- spy: path.join(__dirname, '..'),
- builderf: (builder) => {
- builder.addFile('build/settings.js');
- },
- });
- session = firefox.session;
- browser = firefox.browser;
- http = newApp().listen(port);
-
- await browser.storage.local.set({
- settings,
- });
-
- // Add item into hitories
- await session.navigateTo(`https://i-beam.org/404`);
- });
-
- after(async() => {
- http.close();
- if (firefox) {
- await firefox.close();
- }
- });
-
- beforeEach(async() => {
- await session.navigateTo(`http://127.0.0.1:${port}`);
- body = await session.findElementByCSS('body');
- });
-
- it('should show completions from search engines, bookmarks, and histories by "open" command', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let c = new Console(session);
- await c.sendKeys('open ');
-
- await eventually(async() => {
- let completions = await c.getCompletions();
- assert(completions.find(x => x.type === 'title' && x.text === 'Search Engines'));
- assert(completions.find(x => x.type === 'title' && x.text === 'Bookmarks'));
- assert(completions.find(x => x.type === 'title' && x.text === 'History'));
- });
- });
-
- it('should filter items with URLs by keywords on "open" command', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let c = new Console(session);
- await c.sendKeys('open https://');
-
- await eventually(async() => {
- let completions = await c.getCompletions();
- let items = completions.filter(x => x.type === 'item').map(x => x.text);
- assert(items.every(x => x.includes('https://')));
- });
- })
-
- it('should filter items with titles by keywords on "open" command', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let c = new Console(session);
- await c.sendKeys('open getting');
-
- await eventually(async() => {
- let completions = await c.getCompletions();
- let items = completions.filter(x => x.type === 'item').map(x => x.text);
- assert(items.every(x => x.toLowerCase().includes('getting')));
- });
- })
-
- it('should filter items with titles by keywords on "tabopen" command', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let c = new Console(session);
- await c.sendKeys('tabopen https://');
-
- await eventually(async() => {
- let completions = await c.getCompletions();
- let items = completions.filter(x => x.type === 'item').map(x => x.text);
- assert(items.every(x => x.includes('https://')));
- });
- })
-
- it('should filter items with titles by keywords on "winopen" command', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let c = new Console(session);
- await c.sendKeys('winopen https://');
-
- await eventually(async() => {
- let completions = await c.getCompletions();
- let items = completions.filter(x => x.type === 'item').map(x => x.text);
- assert(items.every(x => x.includes('https://')));
- });
- })
-
- it('should display only specified items in "complete" property by set command', async() => {
- let c = new Console(session);
-
- const execCommand = async(line) => {
- await body.sendKeys(':');
- await session.switchToFrame(0);
- await c.sendKeys(line, Key.Enter);
- await session.switchToParentFrame();
- }
-
- const typeCommand = async(...keys) => {
- await body.sendKeys(':');
- await session.switchToFrame(0);
- await c.sendKeys(...keys);
- }
-
- const cancel = async() => {
- await c.sendKeys(Key.Escape);
- await session.switchToParentFrame();
- }
-
- await execCommand('set complete=sbh');
- await typeCommand('open ');
-
- await eventually(async() => {
- let completions = await c.getCompletions();
- let titles = completions.filter(x => x.type === 'title').map(x => x.text);
- assert.deepEqual(titles, ['Search Engines', 'Bookmarks', 'History'])
- });
-
- await cancel();
- await execCommand('set complete=bss');
- await typeCommand('open ');
-
- await eventually(async() => {
- let completions = await c.getCompletions();
- let titles = completions.filter(x => x.type === 'title').map(x => x.text);
- assert.deepEqual(titles, ['Bookmarks', 'Search Engines', 'Search Engines'])
- });
- })
-
- it('should display only specified items in "complete" property by setting', async() => {
- const settings = {
- source: 'json',
- json: `{
- "keymaps": {
- ":": { "type": "command.show" }
- },
- "search": {
- "default": "google",
- "engines": { "google": "https://google.com/search?q={}" }
- },
- "properties": {
- "complete": "sbh"
- }
- }`,
- };
- await browser.storage.local.set({ settings, });
-
- let c = new Console(session);
-
- const typeCommand = async(...keys) => {
- await body.sendKeys(':');
- await session.switchToFrame(0);
- await c.sendKeys(...keys);
- }
-
- const cancel = async() => {
- await c.sendKeys(Key.Escape);
- await session.switchToParentFrame();
- }
-
- await browser.storage.local.set({ settings: {
- source: 'json',
- json: `{
- "keymaps": {
- ":": { "type": "command.show" }
- },
- "search": {
- "default": "google",
- "engines": { "google": "https://google.com/search?q={}" }
- },
- "properties": {
- "complete": "sbh"
- }
- }`,
- }});
- await typeCommand('open ');
-
- await eventually(async() => {
- let completions = await c.getCompletions();
- let titles = completions.filter(x => x.type === 'title').map(x => x.text);
- assert.deepEqual(titles, ['Search Engines', 'Bookmarks', 'History'])
- });
-
- await cancel();
-
- await browser.storage.local.set({ settings: {
- source: 'json',
- json: `{
- "keymaps": {
- ":": { "type": "command.show" }
- },
- "search": {
- "default": "google",
- "engines": { "google": "https://google.com/search?q={}" }
- },
- "properties": {
- "complete": "bss"
- }
- }`,
- }});
- await typeCommand('open ');
-
- await eventually(async() => {
- let completions = await c.getCompletions();
- let titles = completions.filter(x => x.type === 'title').map(x => x.text);
- assert.deepEqual(titles, ['Bookmarks', 'Search Engines', 'Search Engines'])
- });
-
-
- })
-});
diff --git a/e2e/completion_open.test.ts b/e2e/completion_open.test.ts
new file mode 100644
index 0000000..c957e2e
--- /dev/null
+++ b/e2e/completion_open.test.ts
@@ -0,0 +1,186 @@
+import * as path from 'path';
+import * as assert from 'assert';
+
+import TestServer from './lib/TestServer';
+import settings from './settings';
+import eventually from './eventually';
+import { Builder, Lanthan } from 'lanthan';
+import { WebDriver } from 'selenium-webdriver';
+import Page from './lib/Page';
+
+describe("completion on open/tabopen/winopen commands", () => {
+ let server = new TestServer().receiveContent('/*', 'ok');
+ let lanthan: Lanthan;
+ let webdriver: WebDriver;
+ let browser: any;
+ let page: Page;
+
+ before(async() => {
+ await server.start();
+
+ lanthan = await Builder
+ .forBrowser('firefox')
+ .spyAddon(path.join(__dirname, '..'))
+ .build();
+ webdriver = lanthan.getWebDriver();
+ browser = lanthan.getWebExtBrowser();
+
+ await browser.storage.local.set({
+ settings,
+ });
+
+ // Add item into hitories
+ await webdriver.navigate().to(('https://i-beam.org/404'));
+ });
+
+ after(async() => {
+ await server.stop();
+ if (lanthan) {
+ await lanthan.quit();
+ }
+ });
+
+ beforeEach(async() => {
+ page = await Page.navigateTo(webdriver, server.url());
+ });
+
+ it('should show completions from search engines, bookmarks, and histories by "open" command', async() => {
+ let console = await page.showConsole();
+ await console.inputKeys('open ');
+
+ await eventually(async() => {
+ let completions = await console.getCompletions();
+ assert.ok(completions.find(x => x.type === 'title' && x.text === 'Search Engines'));
+ assert.ok(completions.find(x => x.type === 'title' && x.text === 'Bookmarks'));
+ assert.ok(completions.find(x => x.type === 'title' && x.text === 'History'));
+ });
+ });
+
+ it('should filter items with URLs by keywords on "open" command', async() => {
+ let console = await page.showConsole();
+ await console.inputKeys('open https://');
+
+ await eventually(async() => {
+ let completions = await console.getCompletions();
+ let items = completions.filter(x => x.type === 'item').map(x => x.text);
+ assert.ok(items.every(x => x.includes('https://')));
+ });
+ })
+
+ it('should filter items with titles by keywords on "open" command', async() => {
+ let console = await page.showConsole();
+ await console.inputKeys('open getting');
+
+ await eventually(async() => {
+ let completions = await console.getCompletions();
+ let items = completions.filter(x => x.type === 'item').map(x => x.text);
+ assert.ok(items.every(x => x.toLowerCase().includes('getting')));
+ });
+ })
+
+ it('should filter items with titles by keywords on "tabopen" command', async() => {
+ let console = await page.showConsole();
+ await console.inputKeys('tabopen getting');
+
+ await eventually(async() => {
+ let completions = await console.getCompletions();
+ let items = completions.filter(x => x.type === 'item').map(x => x.text);
+ assert.ok(items.every(x => x.includes('https://')));
+ });
+ })
+
+ it('should filter items with titles by keywords on "winopen" command', async() => {
+ let console = await page.showConsole();
+ await console.inputKeys('winopen https://');
+
+ await eventually(async() => {
+ let completions = await console.getCompletions();
+ let items = completions.filter(x => x.type === 'item').map(x => x.text);
+ assert.ok(items.every(x => x.includes('https://')));
+ });
+ })
+
+ it('should display only specified items in "complete" property by set command', async() => {
+ let console = await page.showConsole();
+ await console.execCommand('set complete=sbh');
+ await (webdriver.switchTo() as any).parentFrame();
+
+ console = await page.showConsole();
+ await console.inputKeys('open ');
+
+ await eventually(async() => {
+ let completions = await console.getCompletions();
+ let titles = completions.filter(x => x.type === 'title').map(x => x.text);
+ assert.deepStrictEqual(titles, ['Search Engines', 'Bookmarks', 'History'])
+ });
+
+ await console.close();
+ console = await page.showConsole();
+ await console.execCommand('set complete=bss');
+ await (webdriver.switchTo() as any).parentFrame();
+
+ console = await page.showConsole();
+ await console.inputKeys('open ');
+
+ await eventually(async() => {
+ let completions = await console.getCompletions();
+ let titles = completions.filter(x => x.type === 'title').map(x => x.text);
+ assert.deepStrictEqual(titles, ['Bookmarks', 'Search Engines', 'Search Engines'])
+ });
+ })
+
+ it('should display only specified items in "complete" property by setting', async() => {
+ await browser.storage.local.set({ settings: {
+ source: 'json',
+ json: `{
+ "keymaps": {
+ ":": { "type": "command.show" }
+ },
+ "search": {
+ "default": "google",
+ "engines": { "google": "https://google.com/search?q={}" }
+ },
+ "properties": {
+ "complete": "sbh"
+ }
+ }`,
+ }});
+
+ let console = await page.showConsole();
+ await console.inputKeys('open ');
+
+ await eventually(async() => {
+ let completions = await console.getCompletions();
+ let titles = completions.filter(x => x.type === 'title').map(x => x.text);
+ assert.deepStrictEqual(titles, ['Search Engines', 'Bookmarks', 'History'])
+ });
+
+ await console.close();
+ await (webdriver.switchTo() as any).parentFrame();
+
+ await browser.storage.local.set({ settings: {
+ source: 'json',
+ json: `{
+ "keymaps": {
+ ":": { "type": "command.show" }
+ },
+ "search": {
+ "default": "google",
+ "engines": { "google": "https://google.com/search?q={}" }
+ },
+ "properties": {
+ "complete": "bss"
+ }
+ }`,
+ }});
+
+ console = await page.showConsole();
+ await console.inputKeys('open ');
+
+ await eventually(async() => {
+ let completions = await console.getCompletions();
+ let titles = completions.filter(x => x.type === 'title').map(x => x.text);
+ assert.deepStrictEqual(titles, ['Bookmarks', 'Search Engines', 'Search Engines'])
+ });
+ })
+});
diff --git a/e2e/completion_set.test.js b/e2e/completion_set.test.js
deleted file mode 100644
index cf5ff5b..0000000
--- a/e2e/completion_set.test.js
+++ /dev/null
@@ -1,75 +0,0 @@
-const express = require('express');
-const lanthan = require('lanthan');
-const path = require('path');
-const assert = require('assert');
-const eventually = require('./eventually');
-const settings = require('./settings');
-const Console = require('./lib/Console');
-
-const Key = lanthan.Key;
-
-describe("completion on set commands", () => {
- const port = 12321;
- let firefox;
- let session;
- let browser;
- let body;
-
- before(async() => {
- firefox = await lanthan.firefox({
- spy: path.join(__dirname, '..'),
- builderf: (builder) => {
- builder.addFile('build/settings.js');
- },
- });
- session = firefox.session;
- browser = firefox.browser;
-
- await browser.storage.local.set({
- settings,
- });
- });
-
- after(async() => {
- if (firefox) {
- await firefox.close();
- }
- });
-
- beforeEach(async() => {
- await session.navigateTo(`about:blank`);
- body = await session.findElementByCSS('body');
- });
-
- it('should show all property names by "set" command with empty params', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let c = new Console(session);
- await c.sendKeys('set ');
-
- await eventually(async() => {
- let items = await c.getCompletions();
- assert.equal(items.length, 5);
- assert.deepEqual(items[0], { type: 'title', text: 'Properties' });
- assert(items[1].text.startsWith('hintchars'))
- assert(items[2].text.startsWith('smoothscroll'))
- assert(items[3].text.startsWith('nosmoothscroll'))
- assert(items[4].text.startsWith('complete'))
- });
- });
-
- it('should show filtered property names by "set" command', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let c = new Console(session);
- await c.sendKeys('set no');
-
- await eventually(async() => {
- let items = await c.getCompletions();
- assert.equal(items.length, 2);
- assert(items[1].text.includes('nosmoothscroll'))
- });
- });
-});
diff --git a/e2e/completion_set.test.ts b/e2e/completion_set.test.ts
new file mode 100644
index 0000000..2a14b2c
--- /dev/null
+++ b/e2e/completion_set.test.ts
@@ -0,0 +1,64 @@
+import * as path from 'path';
+import * as assert from 'assert';
+
+import settings from './settings';
+import eventually from './eventually';
+import { Builder, Lanthan } from 'lanthan';
+import { WebDriver } from 'selenium-webdriver';
+import Page from './lib/Page';
+
+describe("completion on set commands", () => {
+ let lanthan: Lanthan;
+ let webdriver: WebDriver;
+ let browser: any;
+ let page: Page;
+
+ before(async() => {
+ lanthan = await Builder
+ .forBrowser('firefox')
+ .spyAddon(path.join(__dirname, '..'))
+ .build();
+ webdriver = lanthan.getWebDriver();
+ browser = lanthan.getWebExtBrowser();
+
+ await browser.storage.local.set({
+ settings,
+ });
+ });
+
+ after(async() => {
+ if (lanthan) {
+ await lanthan.quit();
+ }
+ });
+
+ beforeEach(async() => {
+ page = await Page.navigateTo(webdriver, `about:blank`);
+ });
+
+ it('should show all property names by "set" command with empty params', async() => {
+ let console = await page.showConsole();
+ await console.inputKeys('set ');
+
+ await eventually(async() => {
+ let items = await console.getCompletions();
+ assert.strictEqual(items.length, 5);
+ assert.deepStrictEqual(items[0], { type: 'title', text: 'Properties' });
+ assert.ok(items[1].text.startsWith('hintchars'))
+ assert.ok(items[2].text.startsWith('smoothscroll'))
+ assert.ok(items[3].text.startsWith('nosmoothscroll'))
+ assert.ok(items[4].text.startsWith('complete'))
+ });
+ });
+
+ it('should show filtered property names by "set" command', async() => {
+ let console = await page.showConsole();
+ await console.inputKeys('set no');
+
+ await eventually(async() => {
+ let items = await console.getCompletions();
+ assert.strictEqual(items.length, 2);
+ assert.ok(items[1].text.includes('nosmoothscroll'))
+ });
+ });
+});
diff --git a/e2e/console.test.js b/e2e/console.test.js
deleted file mode 100644
index 6f6341f..0000000
--- a/e2e/console.test.js
+++ /dev/null
@@ -1,125 +0,0 @@
-const express = require('express');
-const lanthan = require('lanthan');
-const path = require('path');
-const assert = require('assert');
-const eventually = require('./eventually');
-
-const Key = lanthan.Key;
-
-const newApp = () => {
- let app = express();
- app.get('/', (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<html lang="en">
- <head>
- <title>Hello, world!</title>
- </head>
-</html">`);
- });
- return app;
-};
-
-
-describe("console test", () => {
- const port = 12321;
- let http;
- let firefox;
- let session;
- let browser;
- let tab;
- let body;
-
- before(async() => {
- firefox = await lanthan.firefox();
- await firefox.session.installAddonFromPath(path.join(__dirname, '..'));
- session = firefox.session;
- browser = firefox.browser;
- http = newApp().listen(port);
- });
-
- after(async() => {
- http.close();
- if (firefox) {
- await firefox.close();
- }
- });
-
- beforeEach(async() => {
- await session.navigateTo(`http://127.0.0.1:${port}`);
- body = await session.findElementByCSS('body');
- });
-
- it('open console with :', async() => {
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
-
- let input = await session.findElementByCSS('input');
- assert.equal(await input.isDisplayed(), true);
- });
-
- it('open console with open command by o', async() => {
- await body.sendKeys('o');
-
- await session.switchToFrame(0);
- let value = await session.executeScript(() => document.querySelector('input').value);
- assert.equal(value, 'open ');
- });
-
- it('open console with open command and current URL by O', async() => {
- await body.sendKeys(Key.Shift, 'o');
-
- await session.switchToFrame(0);
- let value = await session.executeScript(() => document.querySelector('input').value);
- assert.equal(value, `open http://127.0.0.1:${port}/`);
- });
-
- it('open console with tabopen command by t', async() => {
- await body.sendKeys('t');
-
- await session.switchToFrame(0);
- let value = await session.executeScript(() => document.querySelector('input').value);
- assert.equal(value, 'tabopen ');
- });
-
- it('open console with tabopen command and current URL by T', async() => {
- await body.sendKeys(Key.Shift, 't');
-
- await session.switchToFrame(0);
- let value = await session.executeScript(() => document.querySelector('input').value);
- assert.equal(value, `tabopen http://127.0.0.1:${port}/`);
- });
-
- it('open console with winopen command by w', async() => {
- await body.sendKeys('w');
-
- await session.switchToFrame(0);
- let value = await session.executeScript(() => document.querySelector('input').value);
- assert.equal(value, 'winopen ');
- });
-
- it('open console with winopen command and current URL by W', async() => {
- await body.sendKeys(Key.Shift, 'W');
-
- await session.switchToFrame(0);
- let value = await session.executeScript(() => document.querySelector('input').value);
- assert.equal(value, `winopen http://127.0.0.1:${port}/`);
- });
-
- it('open console with buffer command by b', async() => {
- await body.sendKeys('b');
-
- await session.switchToFrame(0);
- let value = await session.executeScript(() => document.querySelector('input').value);
- assert.equal(value, `buffer `);
- });
-
- it('open console with addbookmark command with title by a', async() => {
- await body.sendKeys('a');
-
- await session.switchToFrame(0);
- let value = await session.executeScript(() => document.querySelector('input').value);
- assert.equal(value, `addbookmark Hello, world!`);
- });
-});
-
diff --git a/e2e/console.test.ts b/e2e/console.test.ts
new file mode 100644
index 0000000..583580a
--- /dev/null
+++ b/e2e/console.test.ts
@@ -0,0 +1,90 @@
+import * as path from 'path';
+import * as assert from 'assert';
+
+import TestServer from './lib/TestServer';
+import { Builder, Lanthan } from 'lanthan';
+import { WebDriver, Key } from 'selenium-webdriver';
+import Page from './lib/Page';
+
+describe("console test", () => {
+ let server = new TestServer().receiveContent('/',
+ `<!DOCTYPE html><html lang="en"><head><title>Hello, world!</title></head></html">`,
+ );
+ let lanthan: Lanthan;
+ let webdriver: WebDriver;
+ let page: Page;
+
+ before(async() => {
+ lanthan = await Builder
+ .forBrowser('firefox')
+ .spyAddon(path.join(__dirname, '..'))
+ .build();
+ webdriver = lanthan.getWebDriver();
+ await server.start();
+ });
+
+ after(async() => {
+ await server.stop();
+ if (lanthan) {
+ await lanthan.quit();
+ }
+ });
+
+ beforeEach(async() => {
+ page = await Page.navigateTo(webdriver, server.url());
+ });
+
+ it('open console with :', async() => {
+ await page.sendKeys(':');
+ let console = await page.getConsole();
+ assert.strictEqual(await console.currentValue(), '');
+ });
+
+ it('open console with open command by o', async() => {
+ await page.sendKeys('o');
+ let console = await page.getConsole();
+ assert.strictEqual(await console.currentValue(), 'open ');
+ });
+
+ it('open console with open command and current URL by O', async() => {
+ await page.sendKeys(Key.SHIFT, 'o');
+ let console = await page.getConsole();
+ assert.strictEqual(await console.currentValue(), `open ${server.url()}`);
+ });
+
+ it('open console with tabopen command by t', async() => {
+ await page.sendKeys('t');
+ let console = await page.getConsole();
+ assert.strictEqual(await console.currentValue(), 'tabopen ');
+ });
+
+ it('open console with tabopen command and current URL by T', async() => {
+ await page.sendKeys(Key.SHIFT, 't');
+ let console = await page.getConsole();
+ assert.strictEqual(await console.currentValue(), `tabopen ${server.url()}`);
+ });
+
+ it('open console with winopen command by w', async() => {
+ await page.sendKeys('w');
+ let console = await page.getConsole();
+ assert.strictEqual(await console.currentValue(), `winopen `);
+ });
+
+ it('open console with winopen command and current URL by W', async() => {
+ await page.sendKeys(Key.SHIFT, 'W');
+ let console = await page.getConsole();
+ assert.strictEqual(await console.currentValue(), `winopen ${server.url()}`);
+ });
+
+ it('open console with buffer command by b', async() => {
+ await page.sendKeys('b');
+ let console = await page.getConsole();
+ assert.strictEqual(await console.currentValue(), `buffer `);
+ });
+
+ it('open console with addbookmark command with title by a', async() => {
+ await page.sendKeys('a');
+ let console = await page.getConsole();
+ assert.strictEqual(await console.currentValue(), `addbookmark Hello, world!`);
+ });
+});
diff --git a/e2e/eventually.js b/e2e/eventually.js
deleted file mode 100644
index ab0ae25..0000000
--- a/e2e/eventually.js
+++ /dev/null
@@ -1,23 +0,0 @@
-let defaultInterval = 100;
-let defaultTimeout = 2000;
-
-function sleep(ms) {
- return new Promise(resolve => setTimeout(resolve, ms));
-}
-
-const eventually = async (fn, timeout = defaultTimeout, interval = defaultInterval) => {
- let start = Date.now();
- let loop = async() => {
- try {
- await fn();
- } catch (err) {
- if (Date.now() - start > timeout) {
- throw err;
- }
- await new Promise((resolve) => setTimeout(resolve, interval))
- await loop();
- }
- };
- await loop();
-};
-module.exports = eventually;
diff --git a/e2e/eventually.ts b/e2e/eventually.ts
new file mode 100644
index 0000000..12c4552
--- /dev/null
+++ b/e2e/eventually.ts
@@ -0,0 +1,30 @@
+const defaultInterval = 100;
+const defaultTimeout = 2000;
+
+type Handler = () => void
+
+const sleep = (ms: number): Promise<void> => {
+ return new Promise(resolve => setTimeout(resolve, ms));
+}
+
+const eventually = async (
+ fn: Handler,
+ timeout = defaultTimeout,
+ interval = defaultInterval,
+): Promise<void> => {
+ let start = Date.now();
+ let loop = async() => {
+ try {
+ await fn();
+ } catch (err) {
+ if (Date.now() - start > timeout) {
+ throw err;
+ }
+ await sleep(interval);
+ await loop();
+ }
+ };
+ await loop();
+};
+
+export default eventually;
diff --git a/e2e/follow.test.js b/e2e/follow.test.js
deleted file mode 100644
index 7e49119..0000000
--- a/e2e/follow.test.js
+++ /dev/null
@@ -1,257 +0,0 @@
-const express = require('express');
-const lanthan = require('lanthan');
-const path = require('path');
-const assert = require('assert');
-const eventually = require('./eventually');
-
-const Key = lanthan.Key;
-
-const newApp = () => {
- let app = express();
-
- app.get('/', (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<html lang="en">
- <body><a href="hello">hello</a></body>
-</html">`);
- });
-
- app.get('/follow-input', (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<html lang="en">
- <body><input></body>
-</html">`);
- });
-
- app.get('/area', (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<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] |
- * | |
- * +-----------------+
- */
- app.get('/test1', (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<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] | |
- * | +-----------+ |
- * | |
- * +-----------------+
- */
- app.get('/test2', (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<html lang="en">
- <body><iframe height="5000" src='/test2-frame'></body>
-</html">`);
- });
- app.get('/test2-frame', (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<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] : |
- * | + - - - - - + |
- * | |
- * +-----------------+
- */
- app.get('/test3', (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<html lang="en">
- <body><iframe src='/test3-frame'></body>
-</html">`);
- });
- app.get('/test3-frame', (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<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 app;
-};
-
-const waitForHints = async(session) => {
- await eventually(async() => {
- let hints = await session.findElementsByCSS('.vimvixen-hint');
- assert(hints.length > 0);
- });
-};
-
-describe('follow test', () => {
-
- const port = 12321;
- let http;
- let firefox;
- let session;
- let browser;
-
- before(async() => {
- http = newApp().listen(port);
-
- firefox = await lanthan.firefox();
- await firefox.session.installAddonFromPath(path.join(__dirname, '..'));
- session = firefox.session;
- browser = firefox.browser;
- });
-
- after(async() => {
- if (firefox) {
- await firefox.close();
- }
- http.close();
- });
-
- afterEach(async() => {
- let tabs = await browser.tabs.query({});
- for (let tab of tabs.slice(1)) {
- await browser.tabs.remove(tab.id);
- }
- });
-
- it('should focus an input by f', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}/follow-input`);
-
- let body = await session.findElementByCSS('body');
- await body.sendKeys('f');
- await waitForHints(session);
- await body.sendKeys('a');
-
- let tagName = await session.executeScript(() => document.activeElement.tagName);
- assert.equal(tagName.toLowerCase(), 'input');
- });
-
- it('should open a link by f', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}/`);
-
- let body = await session.findElementByCSS('body');
- await body.sendKeys('f', 'a');
-
- let hash = await session.executeScript('location.pathname');
- await body.sendKeys(hash, '/hello');
- });
-
- it('should focus an input by F', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}/follow-input`);
-
- let body = await session.findElementByCSS('body');
- await body.sendKeys(Key.Shift, 'f');
- await waitForHints(session);
- await body.sendKeys('a');
-
- let tagName = await session.executeScript(() => document.activeElement.tagName);
- assert.equal(tagName.toLowerCase(), 'input');
- });
-
- it('should open a link to new tab by F', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}/`);
-
- let body = await session.findElementByCSS('body');
- await body.sendKeys(Key.Shift, 'f');
- await waitForHints(session);
- await body.sendKeys('a');
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({});
- assert.equal(tabs.length, 2);
- assert.equal(new URL(tabs[1].url).pathname, '/hello');
- assert.equal(tabs[1].openerTabId, tabs[0].id);
- });
- });
-
- it('should show hints of links in area', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}/area`);
-
- let body = await session.findElementByCSS('body');
- await body.sendKeys(Key.Shift, 'f');
- await eventually(async() => {
- let hints = await session.findElementsByCSS('.vimvixen-hint');
- assert.equal(hints.length, 3);
- });
- });
-
- it('should shows hints only in viewport', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}/test1`);
-
- let body = await session.findElementByCSS('body');
- await body.sendKeys(Key.Shift, 'f');
- await eventually(async() => {
- let hints = await session.findElementsByCSS('.vimvixen-hint');
- assert.equal(hints.length, 1);
- });
- });
-
- it('should shows hints only in window of the frame', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}/test2`);
-
- let body = await session.findElementByCSS('body');
- await body.sendKeys(Key.Shift, 'f');
-
- await session.switchToFrame(0);
- await eventually(async() => {
- let hints = await session.findElementsByCSS('.vimvixen-hint');
- assert.equal(hints.length, 1);
- });
- });
-
- it('should shows hints only in the frame', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}/test3`);
-
- let body = await session.findElementByCSS('body');
- await body.sendKeys(Key.Shift, 'f');
-
- await session.switchToFrame(0);
- await eventually(async() => {
- let hints = await session.findElementsByCSS('.vimvixen-hint');
- assert.equal(hints.length, 1);
- });
- });
-});
diff --git a/e2e/follow.test.ts b/e2e/follow.test.ts
new file mode 100644
index 0000000..fd741ef
--- /dev/null
+++ b/e2e/follow.test.ts
@@ -0,0 +1,216 @@
+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 = () => {
+ let 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', () => {
+ let 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() => {
+ let tabs = await browser.tabs.query({});
+ for (let tab of tabs.slice(1)) {
+ await browser.tabs.remove(tab.id);
+ }
+ });
+
+ it('should focus an input by f', async () => {
+ let page = await Page.navigateTo(webdriver, server.url('/follow-input'));
+ await page.sendKeys('f');
+ await page.waitAndGetHints();
+ await page.sendKeys('a');
+
+ let tagName = await webdriver.executeScript(() => document.activeElement!!.tagName) as string;
+ assert.strictEqual(tagName.toLowerCase(), 'input');
+ });
+
+ it('should open a link by f', async () => {
+ let page = await Page.navigateTo(webdriver, server.url());
+ await page.sendKeys('f');
+ await page.waitAndGetHints();
+ await page.sendKeys('a');
+
+ await eventually(async() => {
+ let hash = await webdriver.executeScript('return location.pathname');
+ assert.strictEqual(hash, '/hello');
+ });
+ });
+
+ it('should focus an input by F', async () => {
+ let page = await Page.navigateTo(webdriver, server.url('/follow-input'));
+ await page.sendKeys(Key.SHIFT, 'f');
+ await page.waitAndGetHints();
+ await page.sendKeys('a');
+
+ let 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 () => {
+ let page = await Page.navigateTo(webdriver, server.url());
+ await page.sendKeys(Key.SHIFT, 'f');
+ await page.waitAndGetHints();
+ await page.sendKeys('a');
+
+ await eventually(async() => {
+ let 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 () => {
+ let page = await Page.navigateTo(webdriver, server.url('/area'));
+ await page.sendKeys(Key.SHIFT, 'f');
+
+ let hints = await page.waitAndGetHints();
+ assert.strictEqual(hints.length, 3);
+ });
+
+ it('should shows hints only in viewport', async () => {
+ let page = await Page.navigateTo(webdriver, server.url('/test1'));
+ await page.sendKeys(Key.SHIFT, 'f');
+
+ let hints = await page.waitAndGetHints();
+ assert.strictEqual(hints.length, 1);
+ });
+
+ it('should shows hints only in window of the frame', async () => {
+ let page = await Page.navigateTo(webdriver, server.url('/test2'));
+ await page.sendKeys(Key.SHIFT, 'f');
+
+ await webdriver.switchTo().frame(0);
+ let hints = await page.waitAndGetHints();
+ assert.strictEqual(hints.length, 1);
+ });
+
+ it('should shows hints only in the frame', async () => {
+ let page = await Page.navigateTo(webdriver, server.url('/test3'));
+ await page.sendKeys(Key.SHIFT, 'f');
+
+ await webdriver.switchTo().frame(0);
+ let hints = await page.waitAndGetHints();
+ assert.strictEqual(hints.length, 1);
+ });
+});
diff --git a/e2e/follow_properties.test.js b/e2e/follow_properties.test.js
deleted file mode 100644
index 223923e..0000000
--- a/e2e/follow_properties.test.js
+++ /dev/null
@@ -1,182 +0,0 @@
-const express = require('express');
-const lanthan = require('lanthan');
-const path = require('path');
-const assert = require('assert');
-const eventually = require('./eventually');
-const Console = require('./lib/Console');
-
-const Key = lanthan.Key;
-
-const newApp = () => {
- let app = express();
-
- app.get('/', (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<html lang="en">
- <body>
- <a href="/">link1</a>
- <a href="/">link2</a>
- <a href="/">link3</a>
- <a href="/">link4</a>
- <a href="/">link5</a>
- </body>
-</html">`);
- });
- return app;
-};
-
-const waitForHints = async(session) => {
- await eventually(async() => {
- let hints = await session.findElementsByCSS('.vimvixen-hint');
- assert(hints.length > 0);
- });
-};
-
-describe('follow properties test', () => {
-
- const port = 12321;
- let http;
- let firefox;
- let session;
- let browser;
- let body;
-
- before(async() => {
- http = newApp().listen(port);
-
- firefox = await lanthan.firefox({
- spy: path.join(__dirname, '..'),
- builderf: (builder) => {
- builder.addFile('build/settings.js');
- },
- });
- session = firefox.session;
- browser = firefox.browser;
-
- await browser.storage.local.set({ settings: {
- source: 'json',
- json: `{
- "keymaps": {
- ":": { "type": "command.show" },
- "f": { "type": "follow.start", "newTab": false },
- "F": { "type": "follow.start", "newTab": true, "background": false },
- "<C-F>": { "type": "follow.start", "newTab": true, "background": true }
- },
- "search": {
- "default": "google",
- "engines": { "google": "https://google.com/search?q={}" }
- },
- "properties": {
- "hintchars": "jk"
- }
- }`,
- }});
- });
-
- after(async() => {
- if (firefox) {
- await firefox.close();
- }
- http.close();
- });
-
- beforeEach(async() => {
- await session.navigateTo(`http://127.0.0.1:${port}/`);
- body = await session.findElementByCSS('body');
- });
-
- afterEach(async() => {
- let tabs = await browser.tabs.query({});
- for (let tab of tabs.slice(1)) {
- await browser.tabs.remove(tab.id);
- }
- });
-
- it('should show hints with hintchars by settings', async () => {
- await body.sendKeys('f');
- await eventually(async() => {
- let hints = await session.findElementsByCSS('.vimvixen-hint');
- assert.equal(hints.length, 5);
-
- assert.equal(await hints[0].getText(), 'J');
- assert.equal(await hints[1].getText(), 'K');
- assert.equal(await hints[2].getText(), 'JJ');
- assert.equal(await hints[3].getText(), 'JK');
- assert.equal(await hints[4].getText(), 'KJ');
- });
-
- await body.sendKeys('j');
-
- await eventually(async() => {
- let hints = await session.findElementsByCSS('.vimvixen-hint');
-
- assert.equal(await hints[0].getStyle('display'), 'block');
- assert.equal(await hints[1].getStyle('display'), 'none');
- assert.equal(await hints[2].getStyle('display'), 'block');
- assert.equal(await hints[3].getStyle('display'), 'block');
- assert.equal(await hints[4].getStyle('display'), 'none');
- });
- });
-
- it('should open tab in background by background:false', async () => {
- await body.sendKeys(Key.Shift, 'f');
- await eventually(async() => {
- let hints = await session.findElementsByCSS('.vimvixen-hint');
- assert.equal(hints.length, 5);
- });
- await body.sendKeys('jj');
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({});
- assert.equal(tabs[0].active, false);
- assert.equal(tabs[1].active, true);
- });
- });
-
- it('should open tab in background by background:true', async () => {
- await body.sendKeys(Key.Control, 'f');
- await eventually(async() => {
- let hints = await session.findElementsByCSS('.vimvixen-hint');
- assert.equal(hints.length, 5);
- });
- await body.sendKeys('jj');
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({});
- assert.equal(tabs[0].active, true);
- assert.equal(tabs[1].active, false);
- });
- });
-
- it('should show hints with hintchars by settings', async () => {
- let c = new Console(session);
-
- await body.sendKeys(':');
- await session.switchToFrame(0);
- await c.sendKeys('set hintchars=abc', Key.Enter);
- await session.switchToParentFrame();
-
- await body.sendKeys('f');
- await eventually(async() => {
- let hints = await session.findElementsByCSS('.vimvixen-hint');
- assert.equal(hints.length, 5);
-
- assert.equal(await hints[0].getText(), 'A');
- assert.equal(await hints[1].getText(), 'B');
- assert.equal(await hints[2].getText(), 'C');
- assert.equal(await hints[3].getText(), 'AA');
- assert.equal(await hints[4].getText(), 'AB');
- });
-
- await body.sendKeys('a');
- await eventually(async() => {
- let hints = await session.findElementsByCSS('.vimvixen-hint');
-
- assert.equal(await hints[0].getStyle('display'), 'block');
- assert.equal(await hints[1].getStyle('display'), 'none');
- assert.equal(await hints[2].getStyle('display'), 'none');
- assert.equal(await hints[3].getStyle('display'), 'block');
- assert.equal(await hints[4].getStyle('display'), 'block');
- });
- });
-});
diff --git a/e2e/follow_properties.test.ts b/e2e/follow_properties.test.ts
new file mode 100644
index 0000000..75a1d77
--- /dev/null
+++ b/e2e/follow_properties.test.ts
@@ -0,0 +1,142 @@
+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';
+
+describe('follow properties test', () => {
+ let server = new TestServer().receiveContent('/', `
+ <!DOCTYPE html>
+ <html lang="en"><body>
+ <a href="/">link1</a>
+ <a href="/">link2</a>
+ <a href="/">link3</a>
+ <a href="/">link4</a>
+ <a href="/">link5</a>
+ </body></html">`);
+
+ let lanthan: Lanthan;
+ let webdriver: WebDriver;
+ let browser: any;
+ let page: Page;
+
+ before(async() => {
+ lanthan = await Builder
+ .forBrowser('firefox')
+ .spyAddon(path.join(__dirname, '..'))
+ .build();
+ webdriver = lanthan.getWebDriver();
+ browser = lanthan.getWebExtBrowser();
+
+ await browser.storage.local.set({ settings: {
+ source: 'json',
+ json: `{
+ "keymaps": {
+ ":": { "type": "command.show" },
+ "f": { "type": "follow.start", "newTab": false },
+ "F": { "type": "follow.start", "newTab": true, "background": false },
+ "<C-F>": { "type": "follow.start", "newTab": true, "background": true }
+ },
+ "search": {
+ "default": "google",
+ "engines": { "google": "https://google.com/search?q={}" }
+ },
+ "properties": {
+ "hintchars": "jk"
+ }
+ }`,
+ }});
+
+ await server.start();
+ });
+
+ after(async() => {
+ await server.stop();
+ if (lanthan) {
+ await lanthan.quit();
+ }
+ });
+
+ beforeEach(async() => {
+ page = await Page.navigateTo(webdriver, server.url());
+ });
+
+ afterEach(async() => {
+ let tabs = await browser.tabs.query({});
+ for (let tab of tabs.slice(1)) {
+ await browser.tabs.remove(tab.id);
+ }
+ });
+
+ it('should show hints with hintchars by settings', async () => {
+ await page.sendKeys('f');
+
+ let hints = await page.waitAndGetHints();
+ assert.strictEqual(hints.length, 5);
+
+ assert.strictEqual(hints[0].text, 'J');
+ assert.strictEqual(hints[1].text, 'K');
+ assert.strictEqual(hints[2].text, 'JJ');
+ assert.strictEqual(hints[3].text, 'JK');
+ assert.strictEqual(hints[4].text, 'KJ');
+
+ await page.sendKeys('j');
+ hints = await page.waitAndGetHints();
+
+ assert.strictEqual(hints[0].displayed, true);
+ assert.strictEqual(hints[1].displayed, false);
+ assert.strictEqual(hints[2].displayed, true);
+ assert.strictEqual(hints[3].displayed, true);
+ assert.strictEqual(hints[4].displayed, false);
+ });
+
+ it('should open tab in background by background:false', async () => {
+ await page.sendKeys(Key.SHIFT, 'f');
+ await page.waitAndGetHints();
+ await page.sendKeys('jj');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({});
+ assert.strictEqual(tabs[0].active, false);
+ assert.strictEqual(tabs[1].active, true);
+ });
+ });
+
+ it('should open tab in background by background:true', async () => {
+ await page.sendKeys(Key.CONTROL, 'f');
+ await page.waitAndGetHints();
+ await page.sendKeys('jj');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({});
+ assert.strictEqual(tabs[0].active, true);
+ assert.strictEqual(tabs[1].active, false);
+ });
+ });
+
+ it('should show hints with hintchars by settings', async () => {
+ let console = await page.showConsole();
+ await console.execCommand('set hintchars=abc');
+ await (webdriver.switchTo() as any).parentFrame();
+
+ await page.sendKeys('f');
+ let hints = await page.waitAndGetHints();
+ assert.strictEqual(hints.length, 5);
+ assert.strictEqual(hints[0].text, 'A');
+ assert.strictEqual(hints[1].text, 'B');
+ assert.strictEqual(hints[2].text, 'C');
+ assert.strictEqual(hints[3].text, 'AA');
+ assert.strictEqual(hints[4].text, 'AB');
+
+ await page.sendKeys('a');
+ hints = await page.waitAndGetHints();
+ assert.strictEqual(hints[0].displayed, true);
+ assert.strictEqual(hints[1].displayed, false);
+ assert.strictEqual(hints[2].displayed, false);
+ assert.strictEqual(hints[3].displayed, true);
+ assert.strictEqual(hints[4].displayed, true);
+ });
+});
diff --git a/e2e/lib/Console.js b/e2e/lib/Console.js
deleted file mode 100644
index 3a39b64..0000000
--- a/e2e/lib/Console.js
+++ /dev/null
@@ -1,41 +0,0 @@
-class Console {
- constructor(session) {
- this.session = session;
- }
-
- async sendKeys(...keys) {
- let input = await this.session.findElementByCSS('input');
- input.sendKeys(...keys);
- }
-
- async currentValue() {
- return await this.session.executeScript(() => {
- let input = document.querySelector('input');
- return input.value;
- });
- }
-
- async getCompletions() {
- return await this.session.executeScript(() => {
- let items = document.querySelectorAll('.vimvixen-console-completion > li');
- if (items.length === 0) {
- throw new Error('completion items not found');
- }
-
- let objs = [];
- for (let li of items) {
- if (li.classList.contains('vimvixen-console-completion-title')) {
- objs.push({ type: 'title', text: li.textContent.trim() });
- } else if ('vimvixen-console-completion-item') {
- let highlight = li.classList.contains('vimvixen-completion-selected');
- objs.push({ type: 'item', text: li.textContent.trim(), highlight });
- } else {
- throw new Error(`unexpected class: ${li.className}`);
- }
- }
- return objs;
- });
- }
-}
-
-module.exports = Console;
diff --git a/e2e/lib/Console.ts b/e2e/lib/Console.ts
new file mode 100644
index 0000000..233bf48
--- /dev/null
+++ b/e2e/lib/Console.ts
@@ -0,0 +1,72 @@
+import { WebDriver, By, Key } from 'selenium-webdriver';
+
+export type CompletionItem = {
+ type: string;
+ text: string;
+ highlight: boolean;
+}
+
+export class Console {
+ constructor(private webdriver: WebDriver) {
+ }
+
+ async sendKeys(...keys: string[]) {
+ let input = await this.webdriver.findElement(By.css('input'));
+ input.sendKeys(...keys);
+ }
+
+ async currentValue() {
+ return await this.webdriver.executeScript(() => {
+ let input = document.querySelector('input');
+ if (input === null) {
+ throw new Error('could not find input element');
+ }
+ return input.value;
+ });
+ }
+
+ 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');
+ if (items.length === 0) {
+ throw new Error('completion items not found');
+ }
+
+ let objs = [];
+ for (let 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') {
+ let highlight = li.classList.contains('vimvixen-completion-selected');
+ objs.push({ type: 'item', text: li.textContent!!.trim(), highlight });
+ } else {
+ throw new Error(`unexpected class: ${li.className}`);
+ }
+ }
+ 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..c49a44f
--- /dev/null
+++ b/e2e/lib/FormOptionPage.ts
@@ -0,0 +1,68 @@
+import { Lanthan } from 'lanthan';
+import { WebDriver, By, until } 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-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 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-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')
+ }
+ await inputs[nth].sendKeys(name);
+ await this.webdriver.executeScript(`document.querySelectorAll('${selector}')[${nth}].blur()`);
+
+ 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')
+ }
+ await inputs[nth].sendKeys(url);
+ await this.webdriver.executeScript(`document.querySelectorAll('${selector}')[${nth}].blur()`);
+ }
+
+ async addBlacklist(): Promise<void> {
+ let rows = await this.webdriver.findElements(By.css(`.form-blacklist-form-row`));
+ let 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})`)));
+ }
+
+ async removeBlackList(nth: number): Promise<void> {
+ let 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')
+ }
+ await buttons[nth].click()
+ }
+
+ async addSearchEngine(): Promise<void> {
+ let rows = await this.webdriver.findElements(By.css(`.form-search-form-row > .column-name`));
+ let 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})`)));
+ }
+
+ async setDefaultSearchEngine(nth: number): Promise<void> {
+ let 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');
+ }
+ 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..c183b06
--- /dev/null
+++ b/e2e/lib/OptionPage.ts
@@ -0,0 +1,39 @@
+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);
+ }
+
+ scrollTo(x: number, y: number): Promise<void> {
+ return this.webdriver.executeScript(`window.scrollTo(${x}, ${y})`);
+ }
+}
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));
+ }
+}
diff --git a/e2e/lib/TestServer.ts b/e2e/lib/TestServer.ts
new file mode 100644
index 0000000..c010e37
--- /dev/null
+++ b/e2e/lib/TestServer.ts
@@ -0,0 +1,64 @@
+import * as http from 'http';
+import * as net from 'net'
+import express from 'express';
+
+type HandlerFunc = (req: express.Request, res: express.Response) => void;
+
+export default class TestServer {
+ private http?: http.Server;
+
+ private app: express.Application;
+
+ constructor(
+ private port = 0,
+ private address = '127.0.0.1',
+ ){
+ this.app = express();
+ }
+
+ handle(path: string, f: HandlerFunc): TestServer {
+ this.app.get(path, f);
+ return this;
+ }
+
+ receiveContent(path: string, content: string): TestServer {
+ this.app.get(path, (_req: express.Request, res: express.Response) => {
+ res.status(200).send(content)
+ });
+ return this;
+ }
+
+ url(path: string = '/'): string {
+ if (!this.http) {
+ throw new Error('http server not started');
+ }
+
+ let addr = this.http.address() as net.AddressInfo;
+ return `http://${addr.address}:${addr.port}${path}`
+ }
+
+ start(): Promise<void> {
+ if (this.http) {
+ throw new Error('http server already started');
+ }
+
+ this.http = http.createServer(this.app)
+ return new Promise((resolve) => {
+ this.http!!.listen(this.port, this.address, () => {
+ resolve();
+ })
+ });
+ }
+
+ stop(): Promise<void> {
+ if (!this.http) {
+ return Promise.resolve();
+ }
+ return new Promise((resolve) => {
+ this.http!!.close(() => {
+ this.http = undefined;
+ resolve();
+ });
+ })
+ }
+}
diff --git a/e2e/lib/clipboard.js b/e2e/lib/clipboard.js
deleted file mode 100644
index 4061dbd..0000000
--- a/e2e/lib/clipboard.js
+++ /dev/null
@@ -1,63 +0,0 @@
-'use strict';
-
-const { spawn } = require('child_process');
-
-const readLinux = () => {
- let stdout = '', stderr = '';
- return new Promise((resolve, reject) => {
- let xsel = spawn('xsel', ['--clipboard', '--output']);
- xsel.stdout.on('data', (data) => {
- stdout += data;
- });
- xsel.stderr.on('data', (data) => {
- stderr += data;
- });
- xsel.on('close', (code) => {
- if (code !== 0) {
- throw new Error(`xsel returns ${code}: ${stderr}`)
- }
- resolve(stdout);
- });
- });
-};
-
-const writeLinux = (data) => {
- let stdout = '', stderr = '';
- return new Promise((resolve, reject) => {
- let xsel = spawn('xsel', ['--clipboard', '--input']);
- xsel.stderr.on('data', (data) => {
- stderr += data;
- });
- xsel.on('close', (code) => {
- if (code !== 0) {
- throw new Error(`xsel returns ${code}: ${stderr}`)
- }
- resolve();
- });
- xsel.stdin.write(data);
- xsel.stdin.end();
- });
-};
-
-const unsupported = (os) => {
- return () => {
- throw new Error(`Unsupported os: ${os}`);
- };
-};
-
-const detect = () => {
- switch (process.platform) {
- case 'linux':
- return {
- read: readLinux,
- write: writeLinux,
- };
- default:
- return {
- read: unsupported(process.platform),
- write: unsupported(process.platform),
- };
- }
-}
-
-module.exports = detect();
diff --git a/e2e/lib/clipboard.ts b/e2e/lib/clipboard.ts
new file mode 100644
index 0000000..c1eddbb
--- /dev/null
+++ b/e2e/lib/clipboard.ts
@@ -0,0 +1,107 @@
+import { spawn } from 'child_process';
+
+const readLinux = (): Promise<string> => {
+ let stdout = '', stderr = '';
+ return new Promise((resolve) => {
+ let xsel = spawn('xsel', ['--clipboard', '--output']);
+ xsel.stdout.on('data', (data) => {
+ stdout += data;
+ });
+ xsel.stderr.on('data', (data) => {
+ stderr += data;
+ });
+ xsel.on('close', (code) => {
+ if (code !== 0) {
+ throw new Error(`xsel returns ${code}: ${stderr}`)
+ }
+ resolve(stdout);
+ });
+ });
+};
+
+const writeLinux = (data: string): Promise<string> => {
+ let stderr = '';
+ return new Promise((resolve) => {
+ let xsel = spawn('xsel', ['--clipboard', '--input']);
+ xsel.stderr.on('data', (data) => {
+ stderr += data;
+ });
+ xsel.on('close', (code) => {
+ if (code !== 0) {
+ throw new Error(`xsel returns ${code}: ${stderr}`)
+ }
+ resolve();
+ });
+ xsel.stdin.write(data);
+ xsel.stdin.end();
+ });
+};
+
+const readDarwin = (): Promise<string> => {
+ let stdout = '', stderr = '';
+ return new Promise((resolve) => {
+ let pbpaste = spawn('pbpaste');
+ pbpaste.stdout.on('data', (data) => {
+ stdout += data;
+ });
+ pbpaste.stderr.on('data', (data) => {
+ stderr += data;
+ });
+ pbpaste.on('close', (code) => {
+ if (code !== 0) {
+ throw new Error(`pbpaste returns ${code}: ${stderr}`)
+ }
+ resolve(stdout);
+ });
+ });
+};
+
+const writeDarwin = (data: string): Promise<string> => {
+ let stderr = '';
+ return new Promise((resolve) => {
+ let pbcopy = spawn('pbcopy');
+ pbcopy.stderr.on('data', (data) => {
+ stderr += data;
+ });
+ pbcopy.on('close', (code) => {
+ if (code !== 0) {
+ throw new Error(`pbcopy returns ${code}: ${stderr}`)
+ }
+ resolve();
+ });
+ pbcopy.stdin.write(data);
+ pbcopy.stdin.end();
+ });
+};
+
+class UnsupportedError extends Error {
+ constructor(platform: string) {
+ super();
+ this.message = `Unsupported platform: ${platform}`;
+ }
+}
+
+const read = () => {
+ switch (process.platform) {
+ 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);
+ }
+ throw new UnsupportedError(process.platform);
+}
+
+export {
+ read,
+ write,
+};
diff --git a/e2e/mark.test.js b/e2e/mark.test.js
deleted file mode 100644
index 8716c1e..0000000
--- a/e2e/mark.test.js
+++ /dev/null
@@ -1,121 +0,0 @@
-const express = require('express');
-const lanthan = require('lanthan');
-const path = require('path');
-const assert = require('assert');
-const eventually = require('./eventually');
-
-const Key = lanthan.Key;
-
-const newApp = () => {
- let app = express();
- app.get('/', (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<html lang="en">
- <body style="width:10000px; height:10000px"></body>
-</html">`);
- });
- return app;
-};
-
-describe("mark test", () => {
-
- const port = 12321;
- let http;
- let firefox;
- let session;
- let browser;
-
- before(async() => {
- http = newApp().listen(port);
-
- firefox = await lanthan.firefox();
- await firefox.session.installAddonFromPath(path.join(__dirname, '..'));
- session = firefox.session;
- browser = firefox.browser;
- });
-
- after(async() => {
- if (firefox) {
- await firefox.close();
- }
- http.close();
- });
-
- it('should set a local mark and jump to it', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}`);
- let body = await session.findElementByCSS('body');
-
- await session.executeScript(() => window.scrollTo(200, 200));
- await body.sendKeys('m', 'a');
- await session.executeScript(() => window.scrollTo(500, 500));
- await body.sendKeys('\'', 'a');
-
- await eventually(async() => {
- let pageXOffset = await session.executeScript(() => window.pageXOffset);
- let pageYOffset = await session.executeScript(() => window.pageYOffset);
- assert.equal(pageXOffset, 200);
- assert.equal(pageYOffset, 200);
- });
- });
-
- it('should set a global mark and jump to it', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}#first`);
- let body = await session.findElementByCSS('body');
-
- await session.executeScript(() => window.scrollTo(200, 200));
- await body.sendKeys('m', 'A');
- await session.executeScript(() => window.scrollTo(500, 500));
- await body.sendKeys('\'', 'A');
-
- await eventually(async() => {
- let pageXOffset = await session.executeScript(() => window.pageXOffset);
- let pageYOffset = await session.executeScript(() => window.pageYOffset);
- assert.equal(pageXOffset, 200);
- assert.equal(pageYOffset, 200);
- });
-
- await browser.tabs.create({ url: `http://127.0.0.1:${port}#second` });
- body = await session.findElementByCSS('body');
- await body.sendKeys('\'', 'A');
-
- await eventually(async() => {
- let tab = (await browser.tabs.query({ active: true }))[0];
- let url = new URL(tab.url);
- assert.equal(url.hash, '#first');
-
- let pageXOffset = await session.executeScript(() => window.pageXOffset);
- let pageYOffset = await session.executeScript(() => window.pageYOffset);
- assert.equal(pageXOffset, 200);
- assert.equal(pageYOffset, 200);
- });
- });
-
- it('set a global mark and creates new tab from gone', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}#first`);
- await session.executeScript(() => window.scrollTo(500, 500));
- let body = await session.findElementByCSS('body');
- await body.sendKeys('m', 'A');
-
- let tab = (await browser.tabs.query({ active: true }))[0];
- await browser.tabs.create({ url: `http://127.0.0.1:${port}#second` });
- await browser.tabs.remove(tab.id);
-
- let handles;
- await eventually(async() => {
- handles = await session.getWindowHandles();
- assert.equal(handles.length, 2);
- });
- await session.switchToWindow(handles[0]);
- await session.navigateTo(`http://127.0.0.1:${port}#second`);
- body = await session.findElementByCSS('body');
- await body.sendKeys('\'', 'A');
-
- await eventually(async() => {
- let tab = (await browser.tabs.query({ active: true }))[0];
- let url = new URL(tab.url);
- assert.equal(url.hash, '#first');
- });
- });
-});
-
-
diff --git a/e2e/mark.test.ts b/e2e/mark.test.ts
new file mode 100644
index 0000000..57a8fa6
--- /dev/null
+++ b/e2e/mark.test.ts
@@ -0,0 +1,102 @@
+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 } from 'selenium-webdriver';
+import Page from './lib/Page';
+
+describe("mark test", () => {
+ let server = new TestServer().receiveContent('/',
+ `<!DOCTYPE html><html lang="en"><body style="width:10000px; height:10000px"></body></html">`,
+ );
+ 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();
+ }
+ });
+
+ it('should set a local mark and jump to it', async () => {
+ let page = await Page.navigateTo(webdriver, server.url());
+ await page.scrollTo(200, 200);
+ await page.sendKeys('m', 'a');
+ await page.scrollTo(500, 500);
+ await page.sendKeys('\'', 'a');
+
+ await eventually(async() => {
+ assert.strictEqual(await page.getScrollX(), 200);
+ assert.strictEqual(await page.getScrollY(), 200);
+ });
+ });
+
+ it('should set a global mark and jump to it', async () => {
+ let page = await Page.navigateTo(webdriver, server.url('/#first'));
+ await page.scrollTo(200, 200);
+ await page.sendKeys('m', 'A');
+ await page.scrollTo(500, 500);
+ await page.sendKeys('\'', 'A');
+
+ await eventually(async() => {
+ assert.strictEqual(await page.getScrollX(), 200);
+ assert.strictEqual(await page.getScrollY(), 200);
+ });
+
+ await browser.tabs.create({ url: server.url('/#second') });
+ page = await Page.currentContext(webdriver);
+ await page.sendKeys('\'', 'A');
+
+ await eventually(async() => {
+ let tab = (await browser.tabs.query({ active: true }))[0];
+ let url = new URL(tab.url);
+ assert.strictEqual(url.hash, '#first');
+
+ assert.strictEqual(await page.getScrollX(), 200);
+ assert.strictEqual(await page.getScrollY(), 200);
+ });
+ });
+
+ it('set a global mark and creates new tab from gone', async () => {
+ let page = await Page.navigateTo(webdriver, server.url('/#first'));
+ await page.scrollTo(500, 500);
+ await page.sendKeys('m', 'A');
+
+ let tab = (await browser.tabs.query({ active: true }))[0];
+ await browser.tabs.create({ url: server.url('/#second') });
+ await browser.tabs.remove(tab.id);
+
+ let handles: string[];
+ await eventually(async() => {
+ handles = await webdriver.getAllWindowHandles();
+ assert.strictEqual(handles.length, 2);
+ });
+ await webdriver.switchTo().window(handles!![0]);
+
+ page = await Page.navigateTo(webdriver, server.url('/#second'));
+ await page.sendKeys('\'', 'A');
+
+ await eventually(async() => {
+ let tab = (await browser.tabs.query({ active: true }))[0];
+ let url = new URL(tab.url);
+ assert.strictEqual(url.hash, '#first');
+ });
+ });
+});
+
+
diff --git a/e2e/navigate.test.js b/e2e/navigate.test.js
deleted file mode 100644
index 17552e5..0000000
--- a/e2e/navigate.test.js
+++ /dev/null
@@ -1,274 +0,0 @@
-const express = require('express');
-const lanthan = require('lanthan');
-const path = require('path');
-const assert = require('assert');
-const eventually = require('./eventually');
-
-const Key = lanthan.Key;
-
-const newApp = () => {
- let app = express();
- app.get('/pagenation-a/:page', (req, res) => {
- res.status(200).send(`
-<html lang="en">
- <a href="/pagenation-a/${Number(req.params.page) - 1}">prev</a>
- <a href="/pagenation-a/${Number(req.params.page) + 1}">next</a>
-</html">`);
- });
- app.get('/pagenation-link/:page', (req, res) => {
- res.status(200).send(`
-<html lang="en">
- <head>
- <link rel="prev" href="/pagenation-link/${Number(req.params.page) - 1}"></link>
- <link rel="next" href="/pagenation-link/${Number(req.params.page) + 1}"></link>
- </head>
-</html">`);
- });
- app.get('/reload', (req, res) => {
- res.status(200).send(`
-<html lang="en">
- <head>
- <script>window.location.hash = Date.now()</script>
- </head>
- <body style="width:10000px; height:10000px"></body>
-</html">`);
- });
-
- app.get('/*', (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<html lang="en">
- ${req.path}
-</html">`);
- });
- return app;
-};
-
-describe("navigate test", () => {
-
- const port = 12321;
- let http;
- let firefox;
- let session;
- let browser;
-
- before(async() => {
- http = newApp().listen(port);
-
- firefox = await lanthan.firefox({
- prefs: {
- 'browser.startup.homepage': `http://127.0.0.1:${port}#home`,
- }
- });
- await firefox.session.installAddonFromPath(path.join(__dirname, '..'));
- session = firefox.session;
- browser = firefox.browser;
- });
-
- after(async() => {
- if (firefox) {
- await firefox.close();
- }
- http.close();
- });
-
- beforeEach(async() => {
- let tabs = await browser.tabs.query({});
- for (let tab of tabs.slice(1)) {
- await browser.tabs.remove(tab.id);
- }
- })
-
- it('should go to parent path without hash by gu', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}/a/b/c`);
- let body = await session.findElementByCSS('body');
-
- await body.sendKeys('g', 'u');
-
- await eventually(async() => {
- let tab = (await browser.tabs.query({}))[0];
- let url = new URL(tab.url);
- assert.equal(url.pathname, `/a/b/`)
- });
- });
-
- it('should remove hash by gu', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}/a/b/c#hash`);
- let body = await session.findElementByCSS('body');
-
- await body.sendKeys('g', 'u');
-
- await eventually(async() => {
- let tab = (await browser.tabs.query({}))[0];
- let url = new URL(tab.url);
- assert.equal(url.hash, '')
- assert.equal(url.pathname, `/a/b/c`)
- });
- });
-
- it('should go to root path by gU', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}/a/b/c#hash`);
- let body = await session.findElementByCSS('body');
-
- await body.sendKeys('g', Key.Shift, 'u');
-
- await eventually(async() => {
- let tab = (await browser.tabs.query({}))[0];
- let url = new URL(tab.url);
- assert.equal(url.pathname, `/`)
- });
- });
-
- it('should go back and forward in history by H and L', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}/first`);
- await session.navigateTo(`http://127.0.0.1:${port}/second`);
- let body = await session.findElementByCSS('body');
-
- await body.sendKeys(Key.Shift, 'h');
-
- await eventually(async() => {
- let tab = (await browser.tabs.query({}))[0];
- let url = new URL(tab.url);
- assert.equal(url.pathname, `/first`)
- });
-
- body = await session.findElementByCSS('body');
- await body.sendKeys(Key.Shift, 'l');
-
- await eventually(async() => {
- tab = (await browser.tabs.query({}))[0];
- url = new URL(tab.url);
- assert.equal(url.pathname, `/second`)
- });
- });
-
- it('should go previous and next page in <a> by [[ and ]]', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}/pagenation-a/10`);
-
- let body = await session.findElementByCSS('body');
- await body.sendKeys('[', '[');
-
- await eventually(async() => {
- let tab = (await browser.tabs.query({}))[0];
- let url = new URL(tab.url);
- assert.equal(url.pathname, '/pagenation-a/9');
- });
- });
-
- it('should go next page in <a> by ]]', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}/pagenation-a/10`);
- let body = await session.findElementByCSS('body');
- await body.sendKeys(']', ']');
-
- await eventually(async() => {
- let tab = (await browser.tabs.query({}))[0];
- let url = new URL(tab.url);
- assert.equal(url.pathname, '/pagenation-a/11');
- });
- });
-
- it('should go previous page in <link> by ]]', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}/pagenation-link/10`);
-
- let body = await session.findElementByCSS('body');
- await body.sendKeys('[', '[');
-
- await eventually(async() => {
- let tab = (await browser.tabs.query({}))[0];
- let url = new URL(tab.url);
- assert.equal(url.pathname, '/pagenation-link/9');
- });
- });
-
- it('should go next page by in <link> by [[', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}/pagenation-link/10`);
- let body = await session.findElementByCSS('body');
- await body.sendKeys(']', ']');
-
- await eventually(async() => {
- let tab = (await browser.tabs.query({}))[0];
- let url = new URL(tab.url);
- assert.equal(url.pathname, '/pagenation-link/11');
- });
- });
-
- it('should go to home page into current tab by gh', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}`);
- let body = await session.findElementByCSS('body');
- await body.sendKeys('g', 'h');
-
- await eventually(async() => {
- let tab = (await browser.tabs.query({}))[0];
- let url = new URL(tab.url);
- assert.equal(url.hash, '#home');
- });
- });
-
- it('should go to home page into current tab by gH', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}`);
- let body = await session.findElementByCSS('body');
- await body.sendKeys('g', Key.Shift, 'H');
-
- await eventually(async() => {
- let tabs = await browser.tabs.query({});
- assert.equal(tabs.length, 2);
- assert.equal(new URL(tabs[0].url).hash, '');
- assert.equal(new URL(tabs[1].url).hash, '#home');
- assert.equal(tabs[1].active, true);
- });
- });
-
- it('should reload current tab by r', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}/reload`);
- await session.executeScript(() => window.scrollTo(500, 500));
- let before
- await eventually(async() => {
- let tab = (await browser.tabs.query({}))[0];
- before = Number(new URL(tab.url).hash.split('#')[1]);
- assert(before > 0);
- });
-
- let body = await session.findElementByCSS('body');
- await body.sendKeys('r');
-
- let after
- await eventually(async() => {
- let tab = (await browser.tabs.query({}))[0];
- after = Number(new URL(tab.url).hash.split('#')[1]);
- assert(after > before);
- });
-
- await eventually(async() => {
- let pageYOffset = await session.executeScript(() => window.pageYOffset);
- assert.equal(pageYOffset, 500);
- });
- });
-
- it('should reload current tab without cache by R', async () => {
- await session.navigateTo(`http://127.0.0.1:${port}/reload`);
- await session.executeScript(() => window.scrollTo(500, 500));
- let before
- await eventually(async() => {
- let tab = (await browser.tabs.query({}))[0];
- before = Number(new URL(tab.url).hash.split('#')[1]);
- assert(before > 0);
- });
-
- let body = await session.findElementByCSS('body');
- await body.sendKeys(Key.Shift, 'R');
-
- let after
- await eventually(async() => {
- let tab = (await browser.tabs.query({}))[0];
- after = Number(new URL(tab.url).hash.split('#')[1]);
- assert(after > before);
- });
-
- // assert that the page offset is reset to 0, and 'eventually' is timed-out.
- await assert.rejects(async () => {
- await eventually(async() => {
- let pageYOffset = await session.executeScript(() => window.pageYOffset);
- assert.equal(pageYOffset, 500);
- });
- });
- });
-});
diff --git a/e2e/navigate.test.ts b/e2e/navigate.test.ts
new file mode 100644
index 0000000..8ee209b
--- /dev/null
+++ b/e2e/navigate.test.ts
@@ -0,0 +1,254 @@
+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 { Options as FirefoxOptions } from 'selenium-webdriver/firefox';
+import Page from './lib/Page';
+
+const newApp = () => {
+ let server = new TestServer();
+ server.handle('/pagenation-a/:page', (req, res) => {
+ res.status(200).send(`
+ <!DOCTYPE html>
+ <html lang="en">
+ <a href="/pagenation-a/${Number(req.params.page) - 1}">prev</a>
+ <a href="/pagenation-a/${Number(req.params.page) + 1}">next</a>
+ </html">`);
+ });
+
+ server.handle('/pagenation-link/:page', (req, res) => {
+ res.status(200).send(`
+ <!DOCTYPE html>
+ <html lang="en">
+ <head>
+ <link rel="prev" href="/pagenation-link/${Number(req.params.page) - 1}"></link>
+ <link rel="next" href="/pagenation-link/${Number(req.params.page) + 1}"></link>
+ </head>
+ </html">`);
+ });
+ server.receiveContent('/reload', `
+ <!DOCTYPE html>
+ <html lang="en">
+ <head>
+ <script>window.location.hash = Date.now()</script>
+ </head>
+ <body style="width:10000px; height:10000px"></body>
+ </html">`);
+
+ server.receiveContent('/*', `ok`);
+
+ return server;
+};
+
+describe("navigate test", () => {
+ let server = newApp();
+ let lanthan: Lanthan;
+ let webdriver: WebDriver;
+ let browser: any;
+
+ before(async() => {
+ await server.start();
+
+ let opts = (new FirefoxOptions() as any)
+ .setPreference('browser.startup.homepage', server.url('/#home'));
+ lanthan = await Builder
+ .forBrowser('firefox')
+ .setOptions(opts)
+ .spyAddon(path.join(__dirname, '..'))
+ .build();
+ webdriver = lanthan.getWebDriver();
+ browser = lanthan.getWebExtBrowser();
+ });
+
+ after(async() => {
+ await server.stop();
+ if (lanthan) {
+ await lanthan.quit();
+ }
+ });
+
+ beforeEach(async() => {
+ let tabs = await browser.tabs.query({});
+ for (let tab of tabs.slice(1)) {
+ await browser.tabs.remove(tab.id);
+ }
+ })
+
+ it('should go to parent path without hash by gu', async () => {
+ let page = await Page.navigateTo(webdriver, server.url('/a/b/c'));
+ await page.sendKeys('g', 'u');
+
+ await eventually(async() => {
+ let tab = (await browser.tabs.query({}))[0];
+ let url = new URL(tab.url);
+ assert.strictEqual(url.pathname, `/a/b/`)
+ });
+ });
+
+ it('should remove hash by gu', async () => {
+ let page = await Page.navigateTo(webdriver, server.url('/a/b/c#hash'));
+ await page.sendKeys('g', 'u');
+
+ await eventually(async() => {
+ let tab = (await browser.tabs.query({}))[0];
+ let url = new URL(tab.url);
+ assert.strictEqual(url.hash, '')
+ assert.strictEqual(url.pathname, `/a/b/c`)
+ });
+ });
+
+ it('should go to root path by gU', async () => {
+ let page = await Page.navigateTo(webdriver, server.url('/a/b/c#hash'));
+ await page.sendKeys('g', Key.SHIFT, 'u');
+
+ await eventually(async() => {
+ let tab = (await browser.tabs.query({}))[0];
+ let url = new URL(tab.url);
+ assert.strictEqual(url.pathname, `/`)
+ });
+ });
+
+ it('should go back and forward in history by H and L', async () => {
+ let page = await Page.navigateTo(webdriver, server.url('/first'));
+ await page.navigateTo(server.url('/second'));
+ await page.sendKeys(Key.SHIFT, 'h');
+
+ await eventually(async() => {
+ let tab = (await browser.tabs.query({}))[0];
+ let url = new URL(tab.url);
+ assert.strictEqual(url.pathname, `/first`)
+ });
+
+ page = await Page.currentContext(webdriver);
+ page.sendKeys(Key.SHIFT, 'l');
+
+ await eventually(async() => {
+ let tab = (await browser.tabs.query({}))[0];
+ let url = new URL(tab.url);
+ assert.strictEqual(url.pathname, `/second`)
+ });
+ });
+
+ it('should go previous and next page in <a> by [[ and ]]', async () => {
+ let page = await Page.navigateTo(webdriver, server.url('/pagenation-a/10'));
+ await page.sendKeys('[', '[');
+
+ await eventually(async() => {
+ let tab = (await browser.tabs.query({}))[0];
+ let url = new URL(tab.url);
+ assert.strictEqual(url.pathname, '/pagenation-a/9');
+ });
+ });
+
+ it('should go next page in <a> by ]]', async () => {
+ let page = await Page.navigateTo(webdriver, server.url('/pagenation-a/10'));
+ await page.sendKeys(']', ']');
+
+ await eventually(async() => {
+ let tab = (await browser.tabs.query({}))[0];
+ let url = new URL(tab.url);
+ assert.strictEqual(url.pathname, '/pagenation-a/11');
+ });
+ });
+
+ it('should go previous page in <link> by ]]', async () => {
+ let page = await Page.navigateTo(webdriver, server.url('/pagenation-link/10'));
+ await page.sendKeys('[', '[');
+
+ await eventually(async() => {
+ let tab = (await browser.tabs.query({}))[0];
+ let url = new URL(tab.url);
+ assert.strictEqual(url.pathname, '/pagenation-link/9');
+ });
+ });
+
+ it('should go next page by in <link> by [[', async () => {
+ let page = await Page.navigateTo(webdriver, server.url('/pagenation-link/10'));
+ await page.sendKeys(']', ']');
+
+ await eventually(async() => {
+ let tab = (await browser.tabs.query({}))[0];
+ let url = new URL(tab.url);
+ assert.strictEqual(url.pathname, '/pagenation-link/11');
+ });
+ });
+
+ it('should go to home page into current tab by gh', async () => {
+ let page = await Page.navigateTo(webdriver, server.url());
+ await page.sendKeys('g', 'h');
+
+ await eventually(async() => {
+ let tab = (await browser.tabs.query({}))[0];
+ let url = new URL(tab.url);
+ assert.strictEqual(url.hash, '#home');
+ });
+ });
+
+ it('should go to home page into current tab by gH', async () => {
+ let page = await Page.navigateTo(webdriver, server.url());
+ await page.sendKeys('g', Key.SHIFT, 'H');
+
+ await eventually(async() => {
+ let tabs = await browser.tabs.query({});
+ assert.strictEqual(tabs.length, 2);
+ assert.strictEqual(new URL(tabs[0].url).hash, '');
+ assert.strictEqual(new URL(tabs[1].url).hash, '#home');
+ assert.strictEqual(tabs[1].active, true);
+ });
+ });
+
+ it('should reload current tab by r', async () => {
+ let page = await Page.navigateTo(webdriver, server.url('/reload'));
+ await page.scrollTo(500, 500);
+
+ let before: number;
+ await eventually(async() => {
+ let tab = (await browser.tabs.query({}))[0];
+ before = Number(new URL(tab.url).hash.split('#')[1]);
+ assert.ok(before > 0);
+ });
+
+ await page.sendKeys('r');
+
+ let after
+ await eventually(async() => {
+ let tab = (await browser.tabs.query({}))[0];
+ after = Number(new URL(tab.url).hash.split('#')[1]);
+ assert.ok(after > before);
+ });
+
+ await eventually(async() => {
+ let page = await Page.currentContext(webdriver);
+ assert.strictEqual(await page.getScrollX(), 500);
+ });
+ });
+
+ it('should reload current tab without cache by R', async () => {
+ let page = await Page.navigateTo(webdriver, server.url('/reload'));
+ await page.scrollTo(500, 500);
+
+ let before: number;
+ await eventually(async() => {
+ let tab = (await browser.tabs.query({}))[0];
+ before = Number(new URL(tab.url).hash.split('#')[1]);
+ assert.ok(before > 0);
+ });
+
+ await page.sendKeys(Key.SHIFT, 'R');
+
+ let after
+ await eventually(async() => {
+ let tab = (await browser.tabs.query({}))[0];
+ after = Number(new URL(tab.url).hash.split('#')[1]);
+ assert.ok(after > before);
+ });
+
+ await eventually(async() => {
+ let page = await Page.currentContext(webdriver);
+ assert.strictEqual(await page.getScrollY(), 0);
+ });
+ });
+});
diff --git a/e2e/options.test.js b/e2e/options.test.js
deleted file mode 100644
index e8045c2..0000000
--- a/e2e/options.test.js
+++ /dev/null
@@ -1,99 +0,0 @@
-const express = require('express');
-const lanthan = require('lanthan');
-const path = require('path');
-const assert = require('assert');
-const eventually = require('./eventually');
-
-const newApp = () => {
- let app = express();
- app.get('/', (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<html lang="en">
- <body style="width:10000px; height:10000px"></body>
-</html">`);
- });
- return app;
-};
-
-describe("options page", () => {
- const port = 12321;
- let http;
- let firefox;
- let session;
- let browser;
-
- before(async() => {
- http = newApp().listen(port);
-
- firefox = await lanthan.firefox({
- spy: path.join(__dirname, '..'),
- builderf: (builder) => {
- builder.addFile('build/settings.js');
- builder.addFile('build/settings.html');
- },
- });
- await firefox.session.installAddonFromPath(path.join(__dirname, '..'));
- session = firefox.session;
- browser = firefox.browser;
- });
-
- after(async() => {
- if (firefox) {
- await firefox.close();
- }
-
- http.close();
- });
-
- beforeEach(async() => {
- let tabs = await browser.tabs.query({});
- for (let tab of tabs.slice(1)) {
- await browser.tabs.remove(tab.id);
- }
- })
-
- const updateTextarea = async(value) => {
- let textarea = await session.findElementByCSS('textarea');
- await session.executeScript(`document.querySelector('textarea').value = '${value}'`)
- await textarea.sendKeys(' ');
- await session.executeScript(() => document.querySelector('textarea').blur());
- }
-
- it('saves current config on blur', async () => {
- let url = await browser.runtime.getURL("build/settings.html")
- await session.navigateTo(url);
-
- await updateTextarea(`{ "blacklist": [ "https://example.com" ] }`);
-
- let { settings } = await browser.storage.local.get('settings');
- assert.equal(settings.source, 'json')
- assert.equal(settings.json, '{ "blacklist": [ "https://example.com" ] } ')
-
- await updateTextarea(`invalid json`);
-
- settings = (await browser.storage.local.get('settings')).settings;
- assert.equal(settings.source, 'json')
- assert.equal(settings.json, '{ "blacklist": [ "https://example.com" ] } ')
-
- let error = await session.findElementByCSS('.settings-ui-input-error');
- let text = await error.getText();
- assert.ok(text.startsWith('SyntaxError:'))
- });
-
- it('updates keymaps without reloading', async () => {
- await browser.tabs.create({ url: `http://127.0.0.1:${port}`, active: false });
- let url = await browser.runtime.getURL("build/settings.html")
- await session.navigateTo(url);
-
- let handles = await session.getWindowHandles();
- await updateTextarea(`{ "keymaps": { "zz": { "type": "scroll.vertically", "count": 10 } } }`);
-
- await session.switchToWindow(handles[1]);
-
- let body = await session.findElementByCSS('body');
- await body.sendKeys('zz')
-
- let y = await session.executeScript(() => window.pageYOffset);
- assert.equal(y, 640);
- })
-});
diff --git a/e2e/options.test.ts b/e2e/options.test.ts
new file mode 100644
index 0000000..8d5023f
--- /dev/null
+++ b/e2e/options.test.ts
@@ -0,0 +1,81 @@
+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 } from 'selenium-webdriver';
+import Page from './lib/Page';
+import OptionPage from './lib/OptionPage';
+
+describe("options page", () => {
+ let server = new TestServer().receiveContent('/',
+ `<!DOCTYPE html><html lang="en"><body style="width:10000px; height:10000px"></body></html">`,
+ );
+ 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() => {
+ if (lanthan) {
+ await lanthan.quit();
+ }
+ await server.stop();
+ });
+
+ beforeEach(async() => {
+ let tabs = await browser.tabs.query({});
+ for (let tab of tabs.slice(1)) {
+ await browser.tabs.remove(tab.id);
+ }
+ })
+
+ it('saves current config on blur', async () => {
+ let page = await OptionPage.open(lanthan);
+ let jsonPage = await page.asJSONOptionPage();
+ await jsonPage.updateSettings(`{ "blacklist": [ "https://example.com" ] }`)
+
+ let { settings } = await browser.storage.local.get('settings');
+ assert.strictEqual(settings.source, 'json')
+ assert.strictEqual(settings.json, '{ "blacklist": [ "https://example.com" ] } ')
+
+ await jsonPage.updateSettings(`invalid json`);
+
+ settings = (await browser.storage.local.get('settings')).settings;
+ assert.strictEqual(settings.source, 'json')
+ assert.strictEqual(settings.json, '{ "blacklist": [ "https://example.com" ] } ')
+
+ let message = await jsonPage.getErrorMessage();
+ assert.ok(message.startsWith('SyntaxError:'))
+ });
+
+ it('updates keymaps without reloading', async () => {
+ let optionPage = await OptionPage.open(lanthan);
+ let jsonPage = await optionPage.asJSONOptionPage();
+ await jsonPage.updateSettings(`{ "keymaps": { "zz": { "type": "scroll.vertically", "count": 10 } } }`);
+
+ await browser.tabs.create({ url: server.url(), active: false });
+ await new Promise((resolve) => setTimeout(resolve, 100));
+ let handles = await webdriver.getAllWindowHandles();
+ await webdriver.switchTo().window(handles[1]);
+
+ let page = await Page.currentContext(webdriver);
+ await page.sendKeys('zz');
+
+ await eventually(async() => {
+ let y = await page.getScrollY();
+ assert.strictEqual(y, 640);
+ });
+ })
+});
diff --git a/e2e/options_form.test.js b/e2e/options_form.test.js
deleted file mode 100644
index f86d995..0000000
--- a/e2e/options_form.test.js
+++ /dev/null
@@ -1,125 +0,0 @@
-const lanthan = require('lanthan');
-const path = require('path');
-const assert = require('assert');
-
-describe("options form page", () => {
- let firefox;
- let session;
- let browser;
-
- beforeEach(async() => {
- firefox = await lanthan.firefox({
- spy: path.join(__dirname, '..'),
- builderf: (builder) => {
- builder.addFile('build/settings.js');
- builder.addFile('build/settings.html');
- },
- });
- await firefox.session.installAddonFromPath(path.join(__dirname, '..'));
- session = firefox.session;
- browser = firefox.browser;
-
- let tabs = await browser.tabs.query({});
- for (let tab of tabs.slice(1)) {
- await browser.tabs.remove(tab.id);
- }
- })
-
- afterEach(async() => {
- if (firefox) {
- await firefox.close();
- }
- })
-
- const setBlacklistValue = async(nth, value) => {
- let selector = '.form-blacklist-form .column-url';
- let input = (await session.findElementsByCSS(selector))[nth];
- await input.sendKeys(value);
- await session.executeScript(`document.querySelectorAll('${selector}')[${nth}].blur()`);
- }
-
- const setSearchEngineValue = async(nth, name, url) => {
- let selector = '.form-search-form input.column-name';
- let input = (await session.findElementsByCSS(selector))[nth];
- await input.sendKeys(name);
- await session.executeScript(`document.querySelectorAll('${selector}')[${nth}].blur()`);
-
- selector = '.form-search-form input.column-url';
- input = (await session.findElementsByCSS(selector))[nth];
- await input.sendKeys(url);
- await session.executeScript(`document.querySelectorAll('${selector}')[${nth}].blur()`);
- }
-
- it('switch to form settings', async () => {
- let url = await browser.runtime.getURL("build/settings.html")
- await session.navigateTo(url);
-
- let useFormInput = await session.findElementByCSS('#setting-source-form');
- await useFormInput.click();
- await session.acceptAlert();
-
- let { settings } = await browser.storage.local.get('settings');
- assert.equal(settings.source, 'form')
- })
-
- it('add blacklist', async () => {
- let url = await browser.runtime.getURL("build/settings.html")
- await session.navigateTo(url);
-
- let useFormInput = await session.findElementByCSS('#setting-source-form');
- await useFormInput.click();
- await session.acceptAlert();
- await session.executeScript(() => window.scrollBy(0, 1000));
-
- // assert default
- let settings = (await browser.storage.local.get('settings')).settings;
- assert.deepEqual(settings.form.blacklist, [])
-
- // add blacklist items
- let addButton = await session.findElementByCSS('.form-blacklist-form .ui-add-button');
- await addButton.click();
- await setBlacklistValue(0, 'google.com')
-
- settings = (await browser.storage.local.get('settings')).settings;
- assert.deepEqual(settings.form.blacklist, ['google.com'])
-
- await addButton.click();
- await setBlacklistValue(1, 'yahoo.com')
-
- settings = (await browser.storage.local.get('settings')).settings;
- assert.deepEqual(settings.form.blacklist, ['google.com', 'yahoo.com'])
-
- // delete first item
- let deleteButton = (await session.findElementsByCSS('.form-blacklist-form .ui-delete-button'))[0];
- await deleteButton.click()
-
- settings = (await browser.storage.local.get('settings')).settings;
- assert.deepEqual(settings.form.blacklist, ['yahoo.com'])
- });
-
- it('add search engines', async () => {
- let url = await browser.runtime.getURL("build/settings.html")
- await session.navigateTo(url);
-
- let useFormInput = await session.findElementByCSS('#setting-source-form');
- await useFormInput.click();
- await session.acceptAlert();
-
- // assert default
- let settings = (await browser.storage.local.get('settings')).settings;
- assert.deepEqual(settings.form.search.default, 'google');
-
- // change default
- let radio = (await session.findElementsByCSS('.form-search-form input[type=radio]'))[2];
- await radio.click();
- settings = (await browser.storage.local.get('settings')).settings;
- assert.deepEqual(settings.form.search.default, 'bing');
-
- let addButton = await session.findElementByCSS('.form-search-form .ui-add-button');
- await addButton.click();
- await setSearchEngineValue(6, 'yippy', 'https://www.yippy.com/search?query={}');
-
- settings = (await browser.storage.local.get('settings')).settings;
- assert.deepEqual(settings.form.search.engines[6], ['yippy', 'https://www.yippy.com/search?query={}']);
- });
-});
diff --git a/e2e/options_form.test.ts b/e2e/options_form.test.ts
new file mode 100644
index 0000000..af53791
--- /dev/null
+++ b/e2e/options_form.test.ts
@@ -0,0 +1,86 @@
+import * as path from 'path';
+import * as assert from 'assert';
+
+import { Builder, Lanthan } from 'lanthan';
+import OptionPage from './lib/OptionPage';
+
+describe("options form page", () => {
+ let lanthan: Lanthan;
+ let browser: any;
+
+ beforeEach(async() => {
+ lanthan = await Builder
+ .forBrowser('firefox')
+ .spyAddon(path.join(__dirname, '..'))
+ .build();
+ browser = lanthan.getWebExtBrowser();
+
+ let tabs = await browser.tabs.query({});
+ for (let tab of tabs.slice(1)) {
+ await browser.tabs.remove(tab.id);
+ }
+ })
+
+ afterEach(async() => {
+ if (lanthan) {
+ await lanthan.quit();
+ }
+ })
+
+ it('switch to form settings', async () => {
+ let page = await OptionPage.open(lanthan);
+ await page.switchToForm();
+
+ let { settings } = await browser.storage.local.get('settings');
+ assert.strictEqual(settings.source, 'form')
+ })
+
+ it('add blacklist', async () => {
+ let page = await OptionPage.open(lanthan);
+ let forms = await page.switchToForm();
+ // Scroll is required to click a button on Firefox 60
+ await page.scrollTo(0, 1000);
+
+ // assert default
+ let settings = (await browser.storage.local.get('settings')).settings;
+ assert.deepStrictEqual(settings.form.blacklist, [])
+
+ // add blacklist items
+ await forms.addBlacklist();
+ await forms.setBlacklist(0, 'google.com')
+
+ settings = (await browser.storage.local.get('settings')).settings;
+ assert.deepStrictEqual(settings.form.blacklist, ['google.com'])
+
+ await forms.addBlacklist();
+ await forms.setBlacklist(1, 'yahoo.com')
+
+ settings = (await browser.storage.local.get('settings')).settings;
+ assert.deepStrictEqual(settings.form.blacklist, ['google.com', 'yahoo.com'])
+
+ // delete first item
+ await forms.removeBlackList(0);
+ settings = (await browser.storage.local.get('settings')).settings;
+ assert.deepStrictEqual(settings.form.blacklist, ['yahoo.com'])
+ });
+
+ it('add search engines', async () => {
+ let page = await OptionPage.open(lanthan);
+ let forms = await page.switchToForm();
+
+ // assert default
+ let settings = (await browser.storage.local.get('settings')).settings;
+ assert.deepStrictEqual(settings.form.search.default, 'google');
+
+ // change default
+ await forms.setDefaultSearchEngine(2);
+ settings = (await browser.storage.local.get('settings')).settings;
+ assert.deepStrictEqual(settings.form.search.default, 'bing');
+
+ await forms.addSearchEngine();
+ await forms.setSearchEngine(6, 'yippy', 'https://www.yippy.com/search?query={}');
+
+ settings = (await browser.storage.local.get('settings')).settings;
+ assert.deepStrictEqual(settings.form.search.engines[6], ['yippy', 'https://www.yippy.com/search?query={}']);
+ });
+});
diff --git a/e2e/repeat.test.js b/e2e/repeat.test.js
deleted file mode 100644
index 4072005..0000000
--- a/e2e/repeat.test.js
+++ /dev/null
@@ -1,92 +0,0 @@
-const express = require('express');
-const lanthan = require('lanthan');
-const path = require('path');
-const assert = require('assert');
-const eventually = require('./eventually');
-
-const Key = lanthan.Key;
-
-const newApp = () => {
- let app = express();
- app.get('/', (req, res) => {
- res.send('ok');
- });
- return app;
-};
-
-describe("tab test", () => {
-
- const port = 12321;
- const url = `http://127.0.0.1:${port}/`;
-
- let http;
- let firefox;
- let session;
- let browser;
- let tabs;
-
- before(async() => {
- firefox = await lanthan.firefox();
- await firefox.session.installAddonFromPath(path.join(__dirname, '..'));
- session = firefox.session;
- browser = firefox.browser;
- http = newApp().listen(port);
-
- await session.navigateTo(`${url}`);
- });
-
- after(async() => {
- http.close();
- if (firefox) {
- await firefox.close();
- }
- });
-
- it('repeats last operation', async () => {
- let before = await browser.tabs.query({});
-
- let body = await session.findElementByCSS('body');
- await body.sendKeys(':');
-
- await session.switchToFrame(0);
- let input = await session.findElementByCSS('input');
- input.sendKeys(`tabopen ${url}newtab`, Key.Enter);
-
- await eventually(async() => {
- let current = await browser.tabs.query({ url: `*://*/newtab` });
- assert.equal(current.length, 1);
- });
-
- body = await session.findElementByCSS('body');
- await body.sendKeys('.');
-
- await eventually(async() => {
- let current = await browser.tabs.query({ url: `*://*/newtab` });
- assert.equal(current.length, 2);
- });
- });
-
- it('repeats last operation', async () => {
- for (let i = 1; i < 5; ++i) {
- await browser.tabs.create({ url: `${url}#${i}` });
- }
- let before = await browser.tabs.query({});
-
- let body = await session.findElementByCSS('body');
- await body.sendKeys('d');
-
- await eventually(async() => {
- let current = await browser.tabs.query({});
- assert.equal(current.length, before.length - 1);
- });
-
- await browser.tabs.update(before[2].id, { active: true });
- body = await session.findElementByCSS('body');
- await body.sendKeys('.');
-
- await eventually(async() => {
- let current = await browser.tabs.query({});
- assert.equal(current.length, before.length - 2);
- });
- });
-});
diff --git a/e2e/repeat.test.ts b/e2e/repeat.test.ts
new file mode 100644
index 0000000..b62272f
--- /dev/null
+++ b/e2e/repeat.test.ts
@@ -0,0 +1,75 @@
+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 } from 'selenium-webdriver';
+import Page from './lib/Page';
+
+describe("tab test", () => {
+ let server = new TestServer().receiveContent('/*', 'ok');
+ 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();
+ }
+ });
+
+ it('repeats last command', async () => {
+ let page = await Page.navigateTo(webdriver, server.url());
+ let console = await page.showConsole();
+ await console.execCommand(`tabopen ${server.url('/newtab')}`);
+
+ await eventually(async() => {
+ let current = await browser.tabs.query({ url: `*://*/newtab` });
+ assert.strictEqual(current.length, 1);
+ });
+
+ page = await Page.currentContext(webdriver);
+ await page.sendKeys('.');
+
+ await eventually(async() => {
+ let current = await browser.tabs.query({ url: `*://*/newtab` });
+ assert.strictEqual(current.length, 2);
+ });
+ });
+
+ it('repeats last operation', async () => {
+ for (let i = 1; i < 5; ++i) {
+ await browser.tabs.create({ url: server.url('/#' + i) });
+ }
+ let before = await browser.tabs.query({});
+
+ let page = await Page.currentContext(webdriver);
+ await page.sendKeys('d');
+
+ await eventually(async() => {
+ let current = await browser.tabs.query({});
+ assert.strictEqual(current.length, before.length - 1);
+ });
+
+ await browser.tabs.update(before[2].id, { active: true });
+ page = await Page.currentContext(webdriver);
+ await page.sendKeys('.');
+
+ await eventually(async() => {
+ let current = await browser.tabs.query({});
+ assert.strictEqual(current.length, before.length - 2);
+ });
+ });
+});
diff --git a/e2e/scroll.test.js b/e2e/scroll.test.js
deleted file mode 100644
index 0ce3ec6..0000000
--- a/e2e/scroll.test.js
+++ /dev/null
@@ -1,150 +0,0 @@
-const express = require('express');
-const lanthan = require('lanthan');
-const path = require('path');
-const assert = require('assert');
-
-const Key = lanthan.Key;
-
-const newApp = () => {
- let app = express();
- app.get('/', (req, res) => {
- res.send(`<!DOCTYPEhtml>
-<html lang="en">
- <body style="width:10000px; height:10000px"></body>
-</html">`);
- });
- return app;
-};
-
-describe("scroll test", () => {
-
- const port = 12321;
- let http;
- let firefox;
- let session;
- let body;
-
- before(async() => {
- http = newApp().listen(port);
-
- firefox = await lanthan.firefox();
- await firefox.session.installAddonFromPath(path.join(__dirname, '..'));
- session = firefox.session;
- });
-
- after(async() => {
- if (firefox) {
- await firefox.close();
- }
- http.close();
- });
-
- beforeEach(async() => {
- await session.navigateTo(`http://127.0.0.1:${port}`);
- body = await session.findElementByCSS('body');
- });
-
-
- it('scrolls up by k', async () => {
- await body.sendKeys('j');
-
- let pageYOffset = await session.executeScript(() => window.pageYOffset);
- assert.equal(pageYOffset, 64);
- });
-
- it('scrolls down by j', async () => {
- await session.executeScript(() => window.scrollTo(0, 200));
- await body.sendKeys('k');
-
- let pageYOffset = await session.executeScript(() => window.pageYOffset);
- assert.equal(pageYOffset, 136);
- });
-
- it('scrolls left by h', async () => {
- await session.executeScript(() => window.scrollTo(100, 100));
- await body.sendKeys('h');
-
- let pageXOffset = await session.executeScript(() => window.pageXOffset);
- assert.equal(pageXOffset, 36);
- });
-
- it('scrolls left by l', async () => {
- await session.executeScript(() => window.scrollTo(100, 100));
- await body.sendKeys('l');
-
- let pageXOffset = await session.executeScript(() => window.pageXOffset);
- assert.equal(pageXOffset, 164);
- });
-
- it('scrolls top by gg', async () => {
- await session.executeScript(() => window.scrollTo(0, 100));
- await body.sendKeys('g', 'g');
-
- let pageYOffset = await session.executeScript(() => window.pageYOffset);
- assert.equal(pageYOffset, 0);
- });
-
- it('scrolls bottom by G', async () => {
- await session.executeScript(() => window.scrollTo(0, 100));
- await body.sendKeys(Key.Shift, 'g');
-
- let pageYOffset = await session.executeScript(() => window.pageYOffset);
- assert(pageYOffset > 5000);
- });
-
- it('scrolls bottom by 0', async () => {
- await session.executeScript(() => window.scrollTo(0, 100));
- await body.sendKeys(Key.Shift, '0');
-
- let pageXOffset = await session.executeScript(() => window.pageXOffset);
- assert(pageXOffset === 0);
- });
-
- it('scrolls bottom by $', async () => {
- await session.executeScript(() => window.scrollTo(0, 100));
- await body.sendKeys(Key.Shift, '$');
-
- let pageXOffset = await session.executeScript(() => window.pageXOffset);
- assert(pageXOffset > 5000);
- });
-
- it('scrolls bottom by <C-U>', async () => {
- await session.executeScript(() => window.scrollTo(0, 1000));
- await body.sendKeys(Key.Control, 'u');
-
- let pageHeight =
- await session.executeScript(() => window.document.documentElement.clientHeight);
- let pageYOffset = await session.executeScript(() => window.pageYOffset);
- assert(Math.abs(pageYOffset - (1000 - Math.floor(pageHeight / 2))) < 5);
- });
-
- it('scrolls bottom by <C-D>', async () => {
- await session.executeScript(() => window.scrollTo(0, 1000));
- await body.sendKeys(Key.Control, 'd');
-
- let pageHeight =
- await session.executeScript(() => window.document.documentElement.clientHeight);
- let pageYOffset = await session.executeScript(() => window.pageYOffset);
- assert(Math.abs(pageYOffset - (1000 + Math.floor(pageHeight / 2))) < 5);
- });
-
- it('scrolls bottom by <C-B>', async () => {
- await session.executeScript(() => window.scrollTo(0, 1000));
- await body.sendKeys(Key.Control, 'b');
-
- let pageHeight =
- await session.executeScript(() => window.document.documentElement.clientHeight);
- let pageYOffset = await session.executeScript(() => window.pageYOffset);
- assert(Math.abs(pageYOffset - (1000 - pageHeight)) < 5);
- });
-
- it('scrolls bottom by <C-F>', async () => {
- await session.executeScript(() => window.scrollTo(0, 1000));
- await body.sendKeys(Key.Control, 'f');
-
- let pageHeight =
- await session.executeScript(() => window.document.documentElement.clientHeight);
- let pageYOffset = await session.executeScript(() => window.pageYOffset);
- assert(Math.abs(pageYOffset - (1000 + pageHeight)) < 5);
- });
-});
diff --git a/e2e/scroll.test.ts b/e2e/scroll.test.ts
new file mode 100644
index 0000000..5145265
--- /dev/null
+++ b/e2e/scroll.test.ts
@@ -0,0 +1,137 @@
+import * as path from 'path';
+import * as assert from 'assert';
+
+import TestServer from './lib/TestServer';
+import { Builder, Lanthan } from 'lanthan';
+import { WebDriver, Key } from 'selenium-webdriver';
+import Page from './lib/Page';
+
+describe("scroll test", () => {
+ let server = new TestServer().receiveContent('/',
+ `<!DOCTYPE html><html lang="en"><body style="width:10000px; height:10000px"></body></html>`,
+ );
+ let lanthan: Lanthan;
+ let webdriver: WebDriver;
+ let page: Page;
+
+ before(async() => {
+ lanthan = await Builder
+ .forBrowser('firefox')
+ .spyAddon(path.join(__dirname, '..'))
+ .build();
+ webdriver = lanthan.getWebDriver();
+ await server.start();
+ });
+
+ after(async() => {
+ await server.stop();
+ if (lanthan) {
+ await lanthan.quit();
+ }
+ });
+
+ beforeEach(async() => {
+ await webdriver.navigate().to(server.url());
+ page = await Page.currentContext(webdriver);
+ });
+
+
+ it('scrolls up by j', async () => {
+ await page.sendKeys('j');
+
+ let scrollY = await page.getScrollY();
+ assert.strictEqual(scrollY, 64);
+ });
+
+ it('scrolls down by k', async () => {
+ await webdriver.executeScript(() => window.scrollTo(0, 200));
+ await page.sendKeys('k');
+
+ let scrollY = await page.getScrollY();
+ assert.strictEqual(scrollY, 136);
+ });
+
+ it('scrolls left by h', async () => {
+ await webdriver.executeScript(() => window.scrollTo(100, 100));
+ await page.sendKeys('h');
+
+ let pageXOffset = await webdriver.executeScript(() => window.pageXOffset) as number;
+ assert.strictEqual(pageXOffset, 36);
+ });
+
+ it('scrolls left by l', async () => {
+ await webdriver.executeScript(() => window.scrollTo(100, 100));
+ await page.sendKeys('l');
+
+ let pageXOffset = await webdriver.executeScript(() => window.pageXOffset) as number;
+ assert.strictEqual(pageXOffset, 164);
+ });
+
+ it('scrolls top by gg', async () => {
+ await webdriver.executeScript(() => window.scrollTo(0, 100));
+ await page.sendKeys('g', 'g');
+
+ let scrollY = await page.getScrollY();
+ assert.strictEqual(scrollY, 0);
+ });
+
+ it('scrolls bottom by G', async () => {
+ await webdriver.executeScript(() => window.scrollTo(0, 100));
+ await page.sendKeys(Key.SHIFT, 'g');
+
+ let scrollY = await page.getScrollY();
+ assert.ok(scrollY > 5000);
+ });
+
+ it('scrolls bottom by 0', async () => {
+ await webdriver.executeScript(() => window.scrollTo(0, 100));
+ await page.sendKeys(Key.SHIFT, '0');
+
+ let pageXOffset = await webdriver.executeScript(() => window.pageXOffset) as number;
+ assert.ok(pageXOffset === 0);
+ });
+
+ it('scrolls bottom by $', async () => {
+ await webdriver.executeScript(() => window.scrollTo(0, 100));
+ await page.sendKeys(Key.SHIFT, '$');
+
+ let pageXOffset = await webdriver.executeScript(() => window.pageXOffset) as number;
+ assert.ok(pageXOffset > 5000);
+ });
+
+ it('scrolls bottom by <C-U>', async () => {
+ await webdriver.executeScript(() => window.scrollTo(0, 1000));
+ await page.sendKeys(Key.CONTROL, 'u');
+
+ let pageHeight = await page.pageHeight();
+ let scrollY = await page.getScrollY();
+ assert.ok(Math.abs(scrollY - (1000 - Math.floor(pageHeight / 2))) < 5);
+ });
+
+ it('scrolls bottom by <C-D>', async () => {
+ await webdriver.executeScript(() => window.scrollTo(0, 1000));
+ await page.sendKeys(Key.CONTROL, 'd');
+
+ let pageHeight = await page.pageHeight();
+ let scrollY = await page.getScrollY();
+ assert.ok(Math.abs(scrollY - (1000 + Math.floor(pageHeight / 2))) < 5);
+ });
+
+ it('scrolls bottom by <C-B>', async () => {
+ await webdriver.executeScript(() => window.scrollTo(0, 1000));
+ await page.sendKeys(Key.CONTROL, 'b');
+
+ let pageHeight = await page.pageHeight();
+ let scrollY = await page.getScrollY();
+ assert.ok(Math.abs(scrollY - (1000 - pageHeight)) < 5);
+ });
+
+ it('scrolls bottom by <C-F>', async () => {
+ await webdriver.executeScript(() => window.scrollTo(0, 1000));
+ await page.sendKeys(Key.CONTROL, 'f');
+
+ let pageHeight = await page.pageHeight();
+ let scrollY = await page.getScrollY();
+ assert.ok(Math.abs(scrollY - (1000 + pageHeight)) < 5);
+ });
+});
diff --git a/e2e/settings.js b/e2e/settings.ts
index e78add0..b88caf0 100644
--- a/e2e/settings.js
+++ b/e2e/settings.ts
@@ -1,4 +1,4 @@
-module.exports = {
+export default {
source: 'json',
json: `{
"keymaps": {
@@ -83,4 +83,4 @@ module.exports = {
"blacklist": [
]
}`,
-}
+};
diff --git a/e2e/tab.test.js b/e2e/tab.test.js
deleted file mode 100644
index 99f0374..0000000
--- a/e2e/tab.test.js
+++ /dev/null
@@ -1,218 +0,0 @@
-const express = require('express');
-const lanthan = require('lanthan');
-const path = require('path');
-const assert = require('assert');
-const eventually = require('./eventually');
-
-const Key = lanthan.Key;
-
-const newApp = () => {
- let app = express();
- app.get('/', (req, res) => {
- res.send('ok');
- });
- return app;
-};
-
-describe("tab test", () => {
-
- const port = 12321;
- const url = `http://127.0.0.1:${port}/`;
-
- let http;
- let firefox;
- let session;
- let browser;
- let win;
- let tabs;
-
- before(async() => {
- firefox = await lanthan.firefox();
- await firefox.session.installAddonFromPath(path.join(__dirname, '..'));
- session = firefox.session;
- browser = firefox.browser;
- http = newApp().listen(port);
- });
-
- after(async() => {
- http.close();
- if (firefox) {
- await firefox.close();
- }
- });
-
- beforeEach(async() => {
- win = await browser.windows.create({ url: `${url}#0` });
- for (let i = 1; i < 5; ++i) {
- await browser.tabs.create({ url: `${url}#${i}`, windowId: win.id });
- await session.navigateTo(`${url}#${i}`);
- }
- tabs = await browser.tabs.query({ windowId: win.id });
- tabs.sort((t1, t2) => t1.index - t2.index);
- });
-
- afterEach(async() => {
- await browser.windows.remove(win.id);
- });
-
- it('deletes tab and selects right by d', async () => {
- await browser.tabs.update(tabs[3].id, { active: true });
- let body = await session.findElementByCSS('body');
- await body.sendKeys('d');
-
- let current = await browser.tabs.query({ windowId: win.id });
- assert(current.length === tabs.length - 1);
- assert(current[3].active);
- assert(current[3].url === tabs[4].url);
- });
-
- it('deletes tab and selects left by D', async () => {
- await browser.tabs.update(tabs[3].id, { active: true });
- let body = await session.findElementByCSS('body');
- await body.sendKeys(Key.Shift, 'D');
-
- await eventually(async() => {
- let current = await browser.tabs.query({ windowId: win.id });
- assert(current.length === tabs.length - 1);
- assert(current[2].active);
- assert(current[2].url === tabs[2].url);
- })
- });
-
- it('deletes all tabs to the right by x$', async () => {
- await browser.tabs.update(tabs[1].id, { active: true });
- let body = await session.findElementByCSS('body');
- await body.sendKeys('x', '$');
-
- let current = await browser.tabs.query({ windowId: win.id });
- assert(current.length === 2);
- });
-
- it('duplicates tab by zd', async () => {
- await browser.tabs.update(tabs[0].id, { active: true });
- let body = await session.findElementByCSS('body');
- await body.sendKeys('z', 'd');
-
- await eventually(async() => {
- let current = await browser.tabs.query({ windowId: win.id });
- current.sort((t1, t2) => t1.index - t2.index);
- assert(current.length === tabs.length + 1);
- assert(current[0].url === current[1].url);
- });
- });
-
- it('makes pinned by zp', async () => {
- await browser.tabs.update(tabs[0].id, { active: true });
- let body = await session.findElementByCSS('body');
- await body.sendKeys('z', 'p');
-
- let current = await browser.tabs.query({ windowId: win.id });
- assert(current[0].pinned);
- });
-
- it('selects previous tab by K', async () => {
- await browser.tabs.update(tabs[2].id, { active: true });
- let body = await session.findElementByCSS('body');
- await body.sendKeys(Key.Shift, 'K');
-
- let current = await browser.tabs.query({ windowId: win.id });
- assert(current[1].active);
- });
-
- it('selects previous tab by K rotatory', async () => {
- await browser.tabs.update(tabs[0].id, { active: true });
- let body = await session.findElementByCSS('body');
- await body.sendKeys(Key.Shift, 'K');
-
- let current = await browser.tabs.query({ windowId: win.id });
- assert(current[current.length - 1].active)
- });
-
- it('selects next tab by J', async () => {
- await browser.tabs.update(tabs[2].id, { active: true });
- let body = await session.findElementByCSS('body');
- await body.sendKeys(Key.Shift, 'J');
-
- let current = await browser.tabs.query({ windowId: win.id });
- assert(current[3].active);
- });
-
- it('selects previous tab by J rotatory', async () => {
- await browser.tabs.update(tabs[tabs.length - 1].id, { active: true });
- let body = await session.findElementByCSS('body');
- await body.sendKeys(Key.Shift, 'J');
-
- let current = await browser.tabs.query({ windowId: win.id });
- assert(current[0].active)
- });
-
- it('selects first tab by g0', async () => {
- await browser.tabs.update(tabs[2].id, { active: true });
- let body = await session.findElementByCSS('body');
- await body.sendKeys('g', '0');
-
- let current = await browser.tabs.query({ windowId: win.id });
- assert(current[0].active)
- });
-
- it('selects last tab by g$', async () => {
- await browser.tabs.update(tabs[2].id, { active: true });
- let body = await session.findElementByCSS('body');
- await body.sendKeys('g', '$');
-
- let current = await browser.tabs.query({ windowId: win.id });
- assert(current[current.length - 1].active)
- });
-
- it('selects last selected tab by <C-6>', async () => {
- await browser.tabs.update(tabs[1].id, { active: true });
- await browser.tabs.update(tabs[4].id, { active: true });
-
- let body = await session.findElementByCSS('body');
- await body.sendKeys(Key.Control, '6');
-
- let current = await browser.tabs.query({ windowId: win.id });
- assert(current[1].active)
- });
-
- // browser.sessions.getRecentlyClosed() sometime throws "An unexpected error occurred"
- // This might be a bug in Firefox.
- it.skip('reopen tab by u', async () => {
- await browser.tabs.remove(tabs[1].id);
- let body = await session.findElementByCSS('body');
- await body.sendKeys('u');
-
- let current = await browser.tabs.query({ windowId: win.id });
- assert(current.length === tabs.length);
- });
-
- it('does not delete pinned tab by d', async () => {
- await browser.tabs.update(tabs[0].id, { active: true, pinned: true });
- let body = await session.findElementByCSS('body');
- await body.sendKeys('d');
-
- let current = await browser.tabs.query({ windowId: win.id });
- assert(current.length === tabs.length);
- });
-
- it('deletes pinned tab by !d', async () => {
- await browser.tabs.update(tabs[0].id, { active: true, pinned: true });
- let body = await session.findElementByCSS('body');
- await body.sendKeys('!', 'd');
-
- let current = await browser.tabs.query({ windowId: win.id });
- assert(current.length === tabs.length - 1);
- });
-
- it('opens view-source by gf', async () => {
- await browser.tabs.update(tabs[0].id, { active: true });
- let body = await session.findElementByCSS('body');
- await body.sendKeys('g', 'f');
-
- await eventually(async() => {
- let current = await browser.tabs.query({ windowId: win.id });
- assert(current.length === tabs.length + 1);
- assert(current[current.length - 1].url === `view-source:${url}#0`);
- });
- });
-});
diff --git a/e2e/tab.test.ts b/e2e/tab.test.ts
new file mode 100644
index 0000000..1a5dd5c
--- /dev/null
+++ b/e2e/tab.test.ts
@@ -0,0 +1,211 @@
+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';
+
+describe("tab test", () => {
+ let server = new TestServer().receiveContent('/*', 'ok');
+ let lanthan: Lanthan;
+ let webdriver: WebDriver;
+ let browser: any;
+ let win: any;
+ let tabs: 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();
+ }
+ });
+
+ beforeEach(async() => {
+ win = await browser.windows.create({ url: server.url('/#0') });
+ for (let i = 1; i < 5; ++i) {
+ await browser.tabs.create({ url: server.url('/#' + i), windowId: win.id });
+ await webdriver.navigate().to(server.url('/#' + i));
+ }
+ tabs = await browser.tabs.query({ windowId: win.id });
+ tabs.sort((t1: any, t2: any) => t1.index - t2.index);
+ });
+
+ afterEach(async() => {
+ await browser.windows.remove(win.id);
+ });
+
+ it('deletes tab and selects right by d', async () => {
+ await browser.tabs.update(tabs[3].id, { active: true });
+ let page = await Page.currentContext(webdriver);
+ await page.sendKeys('d');
+
+ await eventually(async() => {
+ let current = await browser.tabs.query({ windowId: win.id });
+ assert.strictEqual(current.length, tabs.length - 1);
+ assert.strictEqual(current[3].active, true);
+ assert.strictEqual(current[3].id, tabs[4].id);
+ });
+ });
+
+ it('deletes tab and selects left by D', async () => {
+ await browser.tabs.update(tabs[3].id, { active: true });
+ let page = await Page.currentContext(webdriver);
+ await page.sendKeys(Key.SHIFT, 'D');
+
+ await eventually(async() => {
+ let current = await browser.tabs.query({ windowId: win.id });
+ assert.strictEqual(current.length, tabs.length - 1);
+ assert.strictEqual(current[2].active, true);
+ assert.strictEqual(current[2].id, tabs[2].id);
+ })
+ });
+
+ it('deletes all tabs to the right by x$', async () => {
+ await browser.tabs.update(tabs[1].id, { active: true });
+ let page = await Page.currentContext(webdriver);
+ await page.sendKeys('x', '$');
+
+ let current = await browser.tabs.query({ windowId: win.id });
+ assert.strictEqual(current.length, 2);
+ });
+
+ it('duplicates tab by zd', async () => {
+ await browser.tabs.update(tabs[0].id, { active: true });
+ let page = await Page.currentContext(webdriver);
+ await page.sendKeys('z', 'd');
+
+ await eventually(async() => {
+ let current = await browser.tabs.query({ windowId: win.id });
+ current.sort((t1: any, t2: any) => t1.index - t2.index);
+ assert.strictEqual(current.length, tabs.length + 1);
+ assert.strictEqual(current[0].url, current[1].url);
+ });
+ });
+
+ it('makes pinned by zp', async () => {
+ await browser.tabs.update(tabs[0].id, { active: true });
+ let page = await Page.currentContext(webdriver);
+ await page.sendKeys('z', 'p');
+
+ let current = await browser.tabs.query({ windowId: win.id });
+ assert.strictEqual(current[0].pinned, true);
+ });
+
+ it('selects previous tab by K', async () => {
+ await browser.tabs.update(tabs[2].id, { active: true });
+ let page = await Page.currentContext(webdriver);
+ await page.sendKeys(Key.SHIFT, 'K');
+
+ let current = await browser.tabs.query({ windowId: win.id });
+ assert.strictEqual(current[1].active, true);
+ });
+
+ it('selects previous tab by K rotatory', async () => {
+ await browser.tabs.update(tabs[0].id, { active: true });
+ let page = await Page.currentContext(webdriver);
+ await page.sendKeys(Key.SHIFT, 'K');
+
+ let current = await browser.tabs.query({ windowId: win.id });
+ assert.strictEqual(current[current.length - 1].active, true)
+ });
+
+ it('selects next tab by J', async () => {
+ await browser.tabs.update(tabs[2].id, { active: true });
+ let page = await Page.currentContext(webdriver);
+ await page.sendKeys(Key.SHIFT, 'J');
+
+ let current = await browser.tabs.query({ windowId: win.id });
+ assert.strictEqual(current[3].active, true);
+ });
+
+ it('selects previous tab by J rotatory', async () => {
+ await browser.tabs.update(tabs[tabs.length - 1].id, { active: true });
+ let page = await Page.currentContext(webdriver);
+ await page.sendKeys(Key.SHIFT, 'J');
+
+ let current = await browser.tabs.query({ windowId: win.id });
+ assert.strictEqual(current[0].active, true)
+ });
+
+ it('selects first tab by g0', async () => {
+ await browser.tabs.update(tabs[2].id, { active: true });
+ let page = await Page.currentContext(webdriver);
+ await page.sendKeys('g', '0');
+
+ let current = await browser.tabs.query({ windowId: win.id });
+ assert.strictEqual(current[0].active, true)
+ });
+
+ it('selects last tab by g$', async () => {
+ await browser.tabs.update(tabs[2].id, { active: true });
+ let page = await Page.currentContext(webdriver);
+ await page.sendKeys('g', '$');
+
+ let current = await browser.tabs.query({ windowId: win.id });
+ assert.strictEqual(current[current.length - 1].active, true)
+ });
+
+ it('selects last selected tab by <C-6>', async () => {
+ await browser.tabs.update(tabs[1].id, { active: true });
+ await browser.tabs.update(tabs[4].id, { active: true });
+
+ let page = await Page.currentContext(webdriver);
+ await page.sendKeys(Key.CONTROL, '6');
+
+ let current = await browser.tabs.query({ windowId: win.id });
+ assert.strictEqual(current[1].active, true)
+ });
+
+ // browser.sessions.getRecentlyClosed() sometime throws "An unexpected error occurred"
+ // This might be a bug in Firefox.
+ it.skip('reopen tab by u', async () => {
+ await browser.tabs.remove(tabs[1].id);
+ let page = await Page.currentContext(webdriver);
+ await page.sendKeys('u');
+
+ let current = await browser.tabs.query({ windowId: win.id });
+ assert.strictEqual(current.length, tabs.length);
+ });
+
+ it('does not delete pinned tab by d', async () => {
+ await browser.tabs.update(tabs[0].id, { active: true, pinned: true });
+ let page = await Page.currentContext(webdriver);
+ await page.sendKeys('d');
+
+ let current = await browser.tabs.query({ windowId: win.id });
+ assert.strictEqual(current.length, tabs.length);
+ });
+
+ it('deletes pinned tab by !d', async () => {
+ await browser.tabs.update(tabs[0].id, { active: true, pinned: true });
+ let page = await Page.currentContext(webdriver);
+ await page.sendKeys('!', 'd');
+
+ let current = await browser.tabs.query({ windowId: win.id });
+ assert.strictEqual(current.length, tabs.length - 1);
+ });
+
+ it('opens view-source by gf', async () => {
+ await browser.tabs.update(tabs[0].id, { active: true });
+ let page = await Page.currentContext(webdriver);
+ await page.sendKeys('g', 'f');
+
+ await eventually(async() => {
+ let current = await browser.tabs.query({ windowId: win.id });
+ assert.strictEqual(current.length, tabs.length + 1);
+ assert.strictEqual(current[current.length - 1].url, `view-source:${server.url('/#0')}`);
+ });
+ });
+});
diff --git a/e2e/zoom.test.js b/e2e/zoom.test.js
deleted file mode 100644
index 186f67f..0000000
--- a/e2e/zoom.test.js
+++ /dev/null
@@ -1,66 +0,0 @@
-const express = require('express');
-const lanthan = require('lanthan');
-const path = require('path');
-const assert = require('assert');
-const eventually = require('./eventually');
-
-const Key = lanthan.Key;
-
-describe("zoom test", () => {
-
- let firefox;
- let session;
- let browser;
- let tab;
- let body;
-
- before(async() => {
- firefox = await lanthan.firefox();
- await firefox.session.installAddonFromPath(path.join(__dirname, '..'));
- session = firefox.session;
- browser = firefox.browser;
- tab = (await browser.tabs.query({}))[0]
- });
-
- after(async() => {
- if (firefox) {
- await firefox.close();
- }
- });
-
- beforeEach(async() => {
- await session.navigateTo('about:blank');
- body = await session.findElementByCSS('body');
- });
-
- it('should zoom in by zi', async () => {
- let before = await browser.tabs.getZoom(tab.id);
- await body.sendKeys('z', 'i');
-
- await eventually(async() => {
- let actual = await browser.tabs.getZoom(tab.id);
- assert(before < actual);
- });
- });
-
- it('should zoom out by zo', async () => {
- let before = await browser.tabs.getZoom(tab.id);
- await body.sendKeys('z', 'o');
-
- await eventually(async() => {
- let actual = await browser.tabs.getZoom(tab.id);
- assert(before > actual);
- });
- });
-
- it('scrolls left by h', async () => {
- await browser.tabs.setZoom(tab.id, 2);
- await body.sendKeys('z', 'z');
-
- await eventually(async() => {
- let actual = await browser.tabs.getZoom(tab.id);
- assert(actual === 1);
- });
- });
-});
-
diff --git a/e2e/zoom.test.ts b/e2e/zoom.test.ts
new file mode 100644
index 0000000..396ddd2
--- /dev/null
+++ b/e2e/zoom.test.ts
@@ -0,0 +1,65 @@
+import * as path from 'path';
+import * as assert from 'assert';
+
+import eventually from './eventually';
+import { Builder, Lanthan } from 'lanthan';
+import { WebDriver } from 'selenium-webdriver';
+import Page from './lib/Page';
+
+describe("zoom test", () => {
+ let lanthan: Lanthan;
+ let webdriver: WebDriver;
+ let browser: any;
+ let tab: any;
+ let page: Page;
+
+ before(async() => {
+ lanthan = await Builder
+ .forBrowser('firefox')
+ .spyAddon(path.join(__dirname, '..'))
+ .build();
+ webdriver = lanthan.getWebDriver();
+ browser = lanthan.getWebExtBrowser();
+ tab = (await browser.tabs.query({}))[0]
+ page = await Page.currentContext(webdriver);
+ });
+
+ after(async() => {
+ await lanthan.quit();
+ });
+
+ beforeEach(async() => {
+ await webdriver.navigate().to('about:blank');
+ });
+
+ it('should zoom in by zi', async () => {
+ let before = await browser.tabs.getZoom(tab.id);
+ await page.sendKeys('zi');
+
+ await eventually(async() => {
+ let actual = await browser.tabs.getZoom(tab.id);
+ assert.ok(before < actual);
+ });
+ });
+
+ it('should zoom out by zo', async () => {
+ let before = await browser.tabs.getZoom(tab.id);
+ await page.sendKeys('zo');
+
+ await eventually(async() => {
+ let actual = await browser.tabs.getZoom(tab.id);
+ assert.ok(before > actual);
+ });
+ });
+
+ it('should reset zoom by zz', async () => {
+ await browser.tabs.setZoom(tab.id, 2);
+ await page.sendKeys('zz');
+
+ await eventually(async() => {
+ let actual = await browser.tabs.getZoom(tab.id);
+ assert.strictEqual(actual, 1);
+ });
+ });
+});
+