Merge pull request #648 from ueokande/migrate-to-latest-lanthan
Clean E2E tests
This commit is contained in:
commit
4f4396d0a6
64 changed files with 3907 additions and 3986 deletions
|
@ -63,6 +63,13 @@ jobs:
|
|||
- checkout
|
||||
- setup_npm
|
||||
- run: npm run lint
|
||||
- run:
|
||||
# NOTE: Karma loads ts-node automatically and treats karma.conf.js as a TypeScript.
|
||||
# Karma does not starts by karma.conf.js transpile failure, and this hack removes
|
||||
# ts-node module from the local before test.
|
||||
# See: https://github.com/karma-runner/karma/issues/3329
|
||||
name: Remove node-ts from node_modules
|
||||
command: mv node_modules/ts-node node_modules/ts-node.orig
|
||||
- run: npm test
|
||||
- run: npm run package
|
||||
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
|
62
e2e/blacklist.test.ts
Normal file
62
e2e/blacklist.test.ts
Normal file
|
@ -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);
|
||||
});
|
||||
});
|
|
@ -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`,
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
110
e2e/clipboard.test.ts
Normal file
110
e2e/clipboard.test.ts
Normal file
|
@ -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'),
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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`);
|
||||
});
|
||||
});
|
||||
});
|
51
e2e/command_addbookmark.test.ts
Normal file
51
e2e/command_addbookmark.test.ts
Normal file
|
@ -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'));
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
157
e2e/command_bdelete.test.ts
Normal file
157
e2e/command_bdelete.test.ts
Normal file
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
162
e2e/command_buffer.test.ts
Normal file
162
e2e/command_buffer.test.ts
Normal file
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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/')
|
||||
});
|
||||
});
|
||||
});
|
112
e2e/command_open.test.ts
Normal file
112
e2e/command_open.test.ts
Normal file
|
@ -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/')
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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)
|
||||
});
|
||||
});
|
||||
});
|
93
e2e/command_quit.test.ts
Normal file
93
e2e/command_quit.test.ts
Normal file
|
@ -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)
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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/')
|
||||
});
|
||||
});
|
||||
});
|
122
e2e/command_tabopen.test.ts
Normal file
122
e2e/command_tabopen.test.ts
Normal file
|
@ -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/')
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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/')
|
||||
});
|
||||
});
|
||||
});
|
133
e2e/command_winopen.test.ts
Normal file
133
e2e/command_winopen.test.ts
Normal file
|
@ -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/')
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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');
|
||||
});
|
||||
});
|
||||
});
|
100
e2e/completion.test.ts
Normal file
100
e2e/completion.test.ts
Normal file
|
@ -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');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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'));
|
||||
});
|
||||
})
|
||||
});
|
180
e2e/completion_buffers.test.ts
Normal file
180
e2e/completion_buffers.test.ts
Normal file
|
@ -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'));
|
||||
});
|
||||
})
|
||||
});
|
|
@ -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'])
|
||||
});
|
||||
|
||||
|
||||
})
|
||||
});
|
186
e2e/completion_open.test.ts
Normal file
186
e2e/completion_open.test.ts
Normal file
|
@ -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'])
|
||||
});
|
||||
})
|
||||
});
|
|
@ -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'))
|
||||
});
|
||||
});
|
||||
});
|
64
e2e/completion_set.test.ts
Normal file
64
e2e/completion_set.test.ts
Normal file
|
@ -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'))
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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!`);
|
||||
});
|
||||
});
|
||||
|
90
e2e/console.test.ts
Normal file
90
e2e/console.test.ts
Normal file
|
@ -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!`);
|
||||
});
|
||||
});
|
|
@ -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;
|
30
e2e/eventually.ts
Normal file
30
e2e/eventually.ts
Normal file
|
@ -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;
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
216
e2e/follow.test.ts
Normal file
216
e2e/follow.test.ts
Normal file
|
@ -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);
|
||||
});
|
||||
});
|
|
@ -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');
|
||||
});
|
||||
});
|
||||
});
|
142
e2e/follow_properties.test.ts
Normal file
142
e2e/follow_properties.test.ts
Normal file
|
@ -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);
|
||||
});
|
||||
});
|
|
@ -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;
|
72
e2e/lib/Console.ts
Normal file
72
e2e/lib/Console.ts
Normal file
|
@ -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();
|
||||
}
|
||||
}
|
68
e2e/lib/FormOptionPage.ts
Normal file
68
e2e/lib/FormOptionPage.ts
Normal file
|
@ -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();
|
||||
}
|
||||
}
|
22
e2e/lib/JSONOptionPage.ts
Normal file
22
e2e/lib/JSONOptionPage.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
import { Lanthan } from 'lanthan';
|
||||
import { WebDriver, By } from 'selenium-webdriver';
|
||||
|
||||
export default class JSONOptionPage {
|
||||
private webdriver: WebDriver;
|
||||
|
||||
constructor(lanthan: Lanthan) {
|
||||
this.webdriver = lanthan.getWebDriver();
|
||||
}
|
||||
|
||||
async updateSettings(value: string): Promise<void> {
|
||||
let textarea = await this.webdriver.findElement(By.css('textarea'));
|
||||
await this.webdriver.executeScript(`document.querySelector('textarea').value = '${value}'`)
|
||||
await textarea.sendKeys(' ');
|
||||
await this.webdriver.executeScript(() => document.querySelector('textarea')!!.blur());
|
||||
}
|
||||
|
||||
async getErrorMessage(): Promise<string> {
|
||||
let error = await this.webdriver.findElement(By.css('.settings-ui-input-error'));
|
||||
return error.getText();
|
||||
}
|
||||
}
|
39
e2e/lib/OptionPage.ts
Normal file
39
e2e/lib/OptionPage.ts
Normal file
|
@ -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})`);
|
||||
}
|
||||
}
|
93
e2e/lib/Page.ts
Normal file
93
e2e/lib/Page.ts
Normal file
|
@ -0,0 +1,93 @@
|
|||
import { WebDriver, By, until } from 'selenium-webdriver';
|
||||
import { Console } from './Console';
|
||||
|
||||
type Hint = {
|
||||
displayed: boolean,
|
||||
text: string,
|
||||
};
|
||||
|
||||
export default class Page {
|
||||
private constructor(private webdriver: WebDriver) {
|
||||
}
|
||||
|
||||
static async currentContext(webdriver: WebDriver): Promise<Page> {
|
||||
await Page.waitForConsoleLoaded(webdriver);
|
||||
return new Page(webdriver);
|
||||
}
|
||||
|
||||
static async navigateTo(webdriver: WebDriver, url: string): Promise<Page> {
|
||||
await webdriver.navigate().to(url);
|
||||
await Page.waitForConsoleLoaded(webdriver);
|
||||
return new Page(webdriver);
|
||||
}
|
||||
|
||||
async sendKeys(...keys: Array<string|number|Promise<string|number>>): Promise<void> {
|
||||
let body = await this.webdriver.findElement(By.css('body'));
|
||||
await body.sendKeys(...keys);
|
||||
}
|
||||
|
||||
async navigateTo(url: string): Promise<Page> {
|
||||
await this.webdriver.navigate().to(url);
|
||||
await Page.waitForConsoleLoaded(this.webdriver);
|
||||
return new Page(this.webdriver);
|
||||
}
|
||||
|
||||
async showConsole(): Promise<Console> {
|
||||
let iframe = this.webdriver.findElement(By.css('#vimvixen-console-frame'));
|
||||
|
||||
await this.sendKeys(':');
|
||||
await this.webdriver.wait(until.elementIsVisible(iframe));
|
||||
await this.webdriver.switchTo().frame(0);
|
||||
await this.webdriver.wait(until.elementLocated(By.css('input.vimvixen-console-command-input')));
|
||||
return new Console(this.webdriver);
|
||||
}
|
||||
|
||||
async getConsole(): Promise<Console> {
|
||||
let iframe = this.webdriver.findElement(By.css('#vimvixen-console-frame'));
|
||||
|
||||
await this.webdriver.wait(until.elementIsVisible(iframe));
|
||||
await this.webdriver.switchTo().frame(0);
|
||||
return new Console(this.webdriver);
|
||||
}
|
||||
|
||||
async getScrollX(): Promise<number> {
|
||||
return await this.webdriver.executeScript(() => window.pageXOffset);
|
||||
}
|
||||
|
||||
getScrollY(): Promise<number> {
|
||||
return this.webdriver.executeScript(() => window.pageYOffset);
|
||||
}
|
||||
|
||||
scrollTo(x: number, y: number): Promise<void> {
|
||||
return this.webdriver.executeScript(`window.scrollTo(${x}, ${y})`);
|
||||
}
|
||||
|
||||
pageHeight(): Promise<number> {
|
||||
return this.webdriver.executeScript(() => window.document.documentElement.clientHeight);
|
||||
}
|
||||
|
||||
async waitAndGetHints(): Promise<Hint[]> {
|
||||
await this.webdriver.wait(until.elementsLocated(By.css('.vimvixen-hint')));
|
||||
|
||||
let elements = await this.webdriver.findElements(By.css(`.vimvixen-hint`));
|
||||
let hints = [];
|
||||
for (let e of elements) {
|
||||
let display = await e.getCssValue('display');
|
||||
let text = await e.getText();
|
||||
hints.push({
|
||||
displayed: display !== 'none',
|
||||
text: text,
|
||||
});
|
||||
}
|
||||
return hints;
|
||||
}
|
||||
|
||||
private static async waitForConsoleLoaded(webdriver: WebDriver) {
|
||||
let topFrame = await webdriver.executeScript(() => window.top === window);
|
||||
if (!topFrame) {
|
||||
return;
|
||||
}
|
||||
await webdriver.wait(until.elementLocated(By.css('iframe.vimvixen-console-frame')));
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
}
|
||||
}
|
64
e2e/lib/TestServer.ts
Normal file
64
e2e/lib/TestServer.ts
Normal file
|
@ -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();
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
|
@ -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();
|
107
e2e/lib/clipboard.ts
Normal file
107
e2e/lib/clipboard.ts
Normal file
|
@ -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,
|
||||
};
|
121
e2e/mark.test.js
121
e2e/mark.test.js
|
@ -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');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
102
e2e/mark.test.ts
Normal file
102
e2e/mark.test.ts
Normal file
|
@ -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');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
254
e2e/navigate.test.ts
Normal file
254
e2e/navigate.test.ts
Normal file
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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);
|
||||
})
|
||||
});
|
81
e2e/options.test.ts
Normal file
81
e2e/options.test.ts
Normal file
|
@ -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);
|
||||
});
|
||||
})
|
||||
});
|
|
@ -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={}']);
|
||||
});
|
||||
});
|
86
e2e/options_form.test.ts
Normal file
86
e2e/options_form.test.ts
Normal file
|
@ -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={}']);
|
||||
});
|
||||
});
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
75
e2e/repeat.test.ts
Normal file
75
e2e/repeat.test.ts
Normal file
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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);
|
||||
});
|
||||
});
|
137
e2e/scroll.test.ts
Normal file
137
e2e/scroll.test.ts
Normal file
|
@ -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);
|
||||
});
|
||||
});
|
|
@ -1,4 +1,4 @@
|
|||
module.exports = {
|
||||
export default {
|
||||
source: 'json',
|
||||
json: `{
|
||||
"keymaps": {
|
||||
|
@ -83,4 +83,4 @@ module.exports = {
|
|||
"blacklist": [
|
||||
]
|
||||
}`,
|
||||
}
|
||||
};
|
218
e2e/tab.test.js
218
e2e/tab.test.js
|
@ -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`);
|
||||
});
|
||||
});
|
||||
});
|
211
e2e/tab.test.ts
Normal file
211
e2e/tab.test.ts
Normal file
|
@ -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')}`);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
65
e2e/zoom.test.ts
Normal file
65
e2e/zoom.test.ts
Normal file
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -19,8 +19,6 @@ module.exports = function (config) {
|
|||
'test/**/*.html': ['html2js']
|
||||
},
|
||||
|
||||
reporters: ['progress'],
|
||||
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
|
|
590
package-lock.json
generated
590
package-lock.json
generated
|
@ -113,18 +113,64 @@
|
|||
"integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/assert": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/assert/-/assert-1.4.3.tgz",
|
||||
"integrity": "sha512-491hfOvNr0+BGOHT2m36xJ+LK68IuOshvxV0VIrKOnzBDL11WlDa3PwO+drTYkwCdfzJRN9REcDPZVVcrx1ucw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/body-parser": {
|
||||
"version": "1.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.1.tgz",
|
||||
"integrity": "sha512-RoX2EZjMiFMjZh9lmYrwgoP9RTpAjSHiJxdp4oidAQVO02T7HER3xj9UKue5534ULWeqVEkujhWcyvUce+d68w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/connect": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/chai": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.0.tgz",
|
||||
"integrity": "sha512-zw8UvoBEImn392tLjxoavuonblX/4Yb9ha4KBU10FirCfwgzhKO0dvyJSF9ByxV1xK1r2AgnAi/tvQaLgxQqxA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/connect": {
|
||||
"version": "3.4.32",
|
||||
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz",
|
||||
"integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/eslint-visitor-keys": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
|
||||
"integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/express": {
|
||||
"version": "4.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.1.tgz",
|
||||
"integrity": "sha512-VfH/XCP0QbQk5B5puLqTLEeFgR8lfCJHZJKkInZ9mkYd+u8byX0kztXEQxEk4wZXJs8HI+7km2ALXjn4YKcX9w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/body-parser": "*",
|
||||
"@types/express-serve-static-core": "*",
|
||||
"@types/serve-static": "*"
|
||||
}
|
||||
},
|
||||
"@types/express-serve-static-core": {
|
||||
"version": "4.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.9.tgz",
|
||||
"integrity": "sha512-GqpaVWR0DM8FnRUJYKlWgyARoBUAVfRIeVDZQKOttLFp5SmhhF9YFIYeTPwMd/AXfxlP7xVO2dj1fGu0Q+krKQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
"@types/range-parser": "*"
|
||||
}
|
||||
},
|
||||
"@types/hoist-non-react-statics": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
|
||||
|
@ -141,18 +187,36 @@
|
|||
"integrity": "sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/mime": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz",
|
||||
"integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/mocha": {
|
||||
"version": "5.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz",
|
||||
"integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "12.7.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.5.tgz",
|
||||
"integrity": "sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/prop-types": {
|
||||
"version": "15.7.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.1.tgz",
|
||||
"integrity": "sha512-CFzn9idOEpHrgdw8JsoTkaDDyRWk1jrzIV8djzcgpq0y9tG4B4lFT+Nxh52DVpDXV+n4+NPNv7M1Dj5uMp6XFg==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/range-parser": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz",
|
||||
"integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/react": {
|
||||
"version": "16.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.2.tgz",
|
||||
|
@ -207,6 +271,22 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"@types/selenium-webdriver": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-4.0.2.tgz",
|
||||
"integrity": "sha512-N8u76LXU6KmxdfKEhOvK/dNtWUg7aeXrQVRRhVqO1V4gYN7zL6SPPJC3GmauyxYnJtsG1BCegQK77pRwieLVhw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/serve-static": {
|
||||
"version": "1.13.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.3.tgz",
|
||||
"integrity": "sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/express-serve-static-core": "*",
|
||||
"@types/mime": "*"
|
||||
}
|
||||
},
|
||||
"@types/sinon": {
|
||||
"version": "7.0.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-7.0.13.tgz",
|
||||
|
@ -591,6 +671,12 @@
|
|||
"readable-stream": "^2.0.6"
|
||||
}
|
||||
},
|
||||
"arg": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.1.tgz",
|
||||
"integrity": "sha512-SlmP3fEA88MBv0PypnXZ8ZfJhwmDeIE3SP71j37AiXQBXYosPV0x6uISAaHYSlSVhmHOVkomen0tbGk6Anlebw==",
|
||||
"dev": true
|
||||
},
|
||||
"argparse": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||
|
@ -1606,10 +1692,13 @@
|
|||
"dev": true
|
||||
},
|
||||
"content-disposition": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
|
||||
"integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=",
|
||||
"dev": true
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
|
||||
"integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "5.1.2"
|
||||
}
|
||||
},
|
||||
"content-type": {
|
||||
"version": "1.0.4",
|
||||
|
@ -2677,69 +2766,171 @@
|
|||
}
|
||||
},
|
||||
"express": {
|
||||
"version": "4.16.4",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz",
|
||||
"integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==",
|
||||
"version": "4.17.1",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
|
||||
"integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"accepts": "~1.3.5",
|
||||
"accepts": "~1.3.7",
|
||||
"array-flatten": "1.1.1",
|
||||
"body-parser": "1.18.3",
|
||||
"content-disposition": "0.5.2",
|
||||
"body-parser": "1.19.0",
|
||||
"content-disposition": "0.5.3",
|
||||
"content-type": "~1.0.4",
|
||||
"cookie": "0.3.1",
|
||||
"cookie": "0.4.0",
|
||||
"cookie-signature": "1.0.6",
|
||||
"debug": "2.6.9",
|
||||
"depd": "~1.1.2",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"etag": "~1.8.1",
|
||||
"finalhandler": "1.1.1",
|
||||
"finalhandler": "~1.1.2",
|
||||
"fresh": "0.5.2",
|
||||
"merge-descriptors": "1.0.1",
|
||||
"methods": "~1.1.2",
|
||||
"on-finished": "~2.3.0",
|
||||
"parseurl": "~1.3.2",
|
||||
"parseurl": "~1.3.3",
|
||||
"path-to-regexp": "0.1.7",
|
||||
"proxy-addr": "~2.0.4",
|
||||
"qs": "6.5.2",
|
||||
"range-parser": "~1.2.0",
|
||||
"proxy-addr": "~2.0.5",
|
||||
"qs": "6.7.0",
|
||||
"range-parser": "~1.2.1",
|
||||
"safe-buffer": "5.1.2",
|
||||
"send": "0.16.2",
|
||||
"serve-static": "1.13.2",
|
||||
"setprototypeof": "1.1.0",
|
||||
"statuses": "~1.4.0",
|
||||
"type-is": "~1.6.16",
|
||||
"send": "0.17.1",
|
||||
"serve-static": "1.14.1",
|
||||
"setprototypeof": "1.1.1",
|
||||
"statuses": "~1.5.0",
|
||||
"type-is": "~1.6.18",
|
||||
"utils-merge": "1.0.1",
|
||||
"vary": "~1.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"finalhandler": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
|
||||
"integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
|
||||
"accepts": {
|
||||
"version": "1.3.7",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
|
||||
"integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"on-finished": "~2.3.0",
|
||||
"parseurl": "~1.3.2",
|
||||
"statuses": "~1.4.0",
|
||||
"unpipe": "~1.0.0"
|
||||
"mime-types": "~2.1.24",
|
||||
"negotiator": "0.6.2"
|
||||
}
|
||||
},
|
||||
"body-parser": {
|
||||
"version": "1.19.0",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
|
||||
"integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"bytes": "3.1.0",
|
||||
"content-type": "~1.0.4",
|
||||
"debug": "2.6.9",
|
||||
"depd": "~1.1.2",
|
||||
"http-errors": "1.7.2",
|
||||
"iconv-lite": "0.4.24",
|
||||
"on-finished": "~2.3.0",
|
||||
"qs": "6.7.0",
|
||||
"raw-body": "2.4.0",
|
||||
"type-is": "~1.6.17"
|
||||
}
|
||||
},
|
||||
"bytes": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
|
||||
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
|
||||
"dev": true
|
||||
},
|
||||
"cookie": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
|
||||
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
|
||||
"dev": true
|
||||
},
|
||||
"http-errors": {
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
|
||||
"integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"depd": "~1.1.2",
|
||||
"inherits": "2.0.3",
|
||||
"setprototypeof": "1.1.1",
|
||||
"statuses": ">= 1.5.0 < 2",
|
||||
"toidentifier": "1.0.0"
|
||||
}
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safer-buffer": ">= 2.1.2 < 3"
|
||||
}
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.40.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
|
||||
"integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==",
|
||||
"dev": true
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.24",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
|
||||
"integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mime-db": "1.40.0"
|
||||
}
|
||||
},
|
||||
"negotiator": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
|
||||
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
|
||||
"dev": true
|
||||
},
|
||||
"path-to-regexp": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
|
||||
"dev": true
|
||||
},
|
||||
"statuses": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
|
||||
"integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==",
|
||||
"qs": {
|
||||
"version": "6.7.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
||||
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
|
||||
"dev": true
|
||||
},
|
||||
"range-parser": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
|
||||
"dev": true
|
||||
},
|
||||
"raw-body": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
|
||||
"integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"bytes": "3.1.0",
|
||||
"http-errors": "1.7.2",
|
||||
"iconv-lite": "0.4.24",
|
||||
"unpipe": "1.0.0"
|
||||
}
|
||||
},
|
||||
"setprototypeof": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
|
||||
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
|
||||
"dev": true
|
||||
},
|
||||
"type-is": {
|
||||
"version": "1.6.18",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
||||
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"media-typer": "0.3.0",
|
||||
"mime-types": "~2.1.24"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -4496,9 +4687,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"ipaddr.js": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz",
|
||||
"integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=",
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
|
||||
"integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==",
|
||||
"dev": true
|
||||
},
|
||||
"is-accessor-descriptor": {
|
||||
|
@ -5169,128 +5360,16 @@
|
|||
}
|
||||
},
|
||||
"lanthan": {
|
||||
"version": "git+https://github.com/ueokande/lanthan.git#d7f92eb4c1c6eee3f747b4a76bdf39062b4cb58f",
|
||||
"from": "git+https://github.com/ueokande/lanthan.git#master",
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/lanthan/-/lanthan-0.0.2.tgz",
|
||||
"integrity": "sha512-+nWapmVfFCprRE39Z6pKyf5KCclJJvSyAU0o3G2Tl+yZc77xDtqL2JfBADVHk7UNQBrqyg62FPtLq4NeQsFdVA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"commander": "^2.20.0",
|
||||
"express": "^4.16.4",
|
||||
"jszip": "^3.2.1",
|
||||
"express": "^4.17.1",
|
||||
"jszip": "^3.2.2",
|
||||
"request": "^2.88.0",
|
||||
"request-promise-native": "^1.0.7"
|
||||
},
|
||||
"dependencies": {
|
||||
"ajv": {
|
||||
"version": "6.10.0",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz",
|
||||
"integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fast-deep-equal": "^2.0.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"json-schema-traverse": "^0.4.1",
|
||||
"uri-js": "^4.2.2"
|
||||
}
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.20.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
|
||||
"integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==",
|
||||
"dev": true
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
|
||||
"dev": true
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
|
||||
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
|
||||
"dev": true
|
||||
},
|
||||
"har-validator": {
|
||||
"version": "5.1.3",
|
||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
|
||||
"integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "^6.5.5",
|
||||
"har-schema": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||
"dev": true
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.38.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz",
|
||||
"integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==",
|
||||
"dev": true
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.22",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz",
|
||||
"integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mime-db": "~1.38.0"
|
||||
}
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
|
||||
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
|
||||
"dev": true
|
||||
},
|
||||
"request": {
|
||||
"version": "2.88.0",
|
||||
"resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
|
||||
"integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"aws-sign2": "~0.7.0",
|
||||
"aws4": "^1.8.0",
|
||||
"caseless": "~0.12.0",
|
||||
"combined-stream": "~1.0.6",
|
||||
"extend": "~3.0.2",
|
||||
"forever-agent": "~0.6.1",
|
||||
"form-data": "~2.3.2",
|
||||
"har-validator": "~5.1.0",
|
||||
"http-signature": "~1.2.0",
|
||||
"is-typedarray": "~1.0.0",
|
||||
"isstream": "~0.1.2",
|
||||
"json-stringify-safe": "~5.0.1",
|
||||
"mime-types": "~2.1.19",
|
||||
"oauth-sign": "~0.9.0",
|
||||
"performance-now": "^2.1.0",
|
||||
"qs": "~6.5.2",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"tough-cookie": "~2.4.3",
|
||||
"tunnel-agent": "^0.6.0",
|
||||
"uuid": "^3.3.2"
|
||||
}
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "2.4.3",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
|
||||
"integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"psl": "^1.1.24",
|
||||
"punycode": "^1.4.1"
|
||||
}
|
||||
},
|
||||
"uuid": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
|
||||
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
|
||||
"dev": true
|
||||
}
|
||||
"request-promise-native": "^1.0.7",
|
||||
"selenium-webdriver": "^4.0.0-alpha.5"
|
||||
}
|
||||
},
|
||||
"lcid": {
|
||||
|
@ -5558,6 +5637,12 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"make-error": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz",
|
||||
"integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==",
|
||||
"dev": true
|
||||
},
|
||||
"mamacro": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz",
|
||||
|
@ -6948,9 +7033,9 @@
|
|||
}
|
||||
},
|
||||
"parseurl": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
|
||||
"integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=",
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
|
||||
"dev": true
|
||||
},
|
||||
"pascalcase": {
|
||||
|
@ -7278,13 +7363,13 @@
|
|||
}
|
||||
},
|
||||
"proxy-addr": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz",
|
||||
"integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==",
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz",
|
||||
"integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"forwarded": "~0.1.2",
|
||||
"ipaddr.js": "1.8.0"
|
||||
"ipaddr.js": "1.9.0"
|
||||
}
|
||||
},
|
||||
"prr": {
|
||||
|
@ -7991,6 +8076,12 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"sax": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
||||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
|
||||
"dev": true
|
||||
},
|
||||
"scheduler": {
|
||||
"version": "0.15.0",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.15.0.tgz",
|
||||
|
@ -8033,6 +8124,52 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"selenium-webdriver": {
|
||||
"version": "4.0.0-alpha.5",
|
||||
"resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.0.0-alpha.5.tgz",
|
||||
"integrity": "sha512-hktl3DSrhzM59yLhWzDGHIX9o56DvA+cVK7Dw6FcJR6qQ4CGzkaHeXQPcdrslkWMTeq0Ci9AmCxq0EMOvm2Rkg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"jszip": "^3.1.5",
|
||||
"rimraf": "^2.6.3",
|
||||
"tmp": "0.0.30",
|
||||
"xml2js": "^0.4.19"
|
||||
},
|
||||
"dependencies": {
|
||||
"glob": {
|
||||
"version": "7.1.4",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
|
||||
"integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
||||
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob": "^7.1.3"
|
||||
}
|
||||
},
|
||||
"tmp": {
|
||||
"version": "0.0.30",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz",
|
||||
"integrity": "sha1-ckGdSovn1s51FI/YsyTlk6cRwu0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"os-tmpdir": "~1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
|
||||
|
@ -8040,9 +8177,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"send": {
|
||||
"version": "0.16.2",
|
||||
"resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
|
||||
"integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
|
||||
"integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
|
@ -8052,24 +8189,55 @@
|
|||
"escape-html": "~1.0.3",
|
||||
"etag": "~1.8.1",
|
||||
"fresh": "0.5.2",
|
||||
"http-errors": "~1.6.2",
|
||||
"mime": "1.4.1",
|
||||
"ms": "2.0.0",
|
||||
"http-errors": "~1.7.2",
|
||||
"mime": "1.6.0",
|
||||
"ms": "2.1.1",
|
||||
"on-finished": "~2.3.0",
|
||||
"range-parser": "~1.2.0",
|
||||
"statuses": "~1.4.0"
|
||||
"range-parser": "~1.2.1",
|
||||
"statuses": "~1.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"mime": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
|
||||
"integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
|
||||
"http-errors": {
|
||||
"version": "1.7.3",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz",
|
||||
"integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"depd": "~1.1.2",
|
||||
"inherits": "2.0.4",
|
||||
"setprototypeof": "1.1.1",
|
||||
"statuses": ">= 1.5.0 < 2",
|
||||
"toidentifier": "1.0.0"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true
|
||||
},
|
||||
"statuses": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
|
||||
"integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==",
|
||||
"mime": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
||||
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
|
||||
"dev": true
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
|
||||
"dev": true
|
||||
},
|
||||
"range-parser": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
|
||||
"dev": true
|
||||
},
|
||||
"setprototypeof": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
|
||||
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
|
@ -8081,15 +8249,15 @@
|
|||
"dev": true
|
||||
},
|
||||
"serve-static": {
|
||||
"version": "1.13.2",
|
||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
|
||||
"integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
|
||||
"integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"parseurl": "~1.3.2",
|
||||
"send": "0.16.2"
|
||||
"parseurl": "~1.3.3",
|
||||
"send": "0.17.1"
|
||||
}
|
||||
},
|
||||
"set-blocking": {
|
||||
|
@ -9096,6 +9264,12 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"toidentifier": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
|
||||
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
|
||||
"dev": true
|
||||
},
|
||||
"toposort": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz",
|
||||
|
@ -9228,6 +9402,27 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"ts-node": {
|
||||
"version": "8.4.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.4.1.tgz",
|
||||
"integrity": "sha512-5LpRN+mTiCs7lI5EtbXmF/HfMeCjzt7DH9CZwtkr6SywStrNQC723wG+aOWFiLNn7zT3kD/RnFqi3ZUfr4l5Qw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"arg": "^4.1.0",
|
||||
"diff": "^4.0.1",
|
||||
"make-error": "^1.1.1",
|
||||
"source-map-support": "^0.5.6",
|
||||
"yn": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"diff": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz",
|
||||
"integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"tslib": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
|
||||
|
@ -10102,6 +10297,23 @@
|
|||
"ultron": "~1.1.0"
|
||||
}
|
||||
},
|
||||
"xml2js": {
|
||||
"version": "0.4.22",
|
||||
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.22.tgz",
|
||||
"integrity": "sha512-MWTbxAQqclRSTnehWWe5nMKzI3VmJ8ltiJEco8akcC6j3miOhjjfzKum5sId+CWhfxdOs/1xauYr8/ZDBtQiRw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"sax": ">=0.6.0",
|
||||
"util.promisify": "~1.0.0",
|
||||
"xmlbuilder": "~11.0.0"
|
||||
}
|
||||
},
|
||||
"xmlbuilder": {
|
||||
"version": "11.0.1",
|
||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
|
||||
"integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
|
||||
"dev": true
|
||||
},
|
||||
"xmlhttprequest-ssl": {
|
||||
"version": "1.5.5",
|
||||
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
|
||||
|
@ -10304,6 +10516,12 @@
|
|||
"resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
|
||||
"integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=",
|
||||
"dev": true
|
||||
},
|
||||
"yn": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
10
package.json
10
package.json
|
@ -8,7 +8,7 @@
|
|||
"lint": "eslint --ext .js,.jsx,.ts,.tsx src",
|
||||
"type-checks": "tsc --noEmit",
|
||||
"test": "karma start",
|
||||
"test:e2e": "mocha --timeout 10000 --retries 5 e2e"
|
||||
"test:e2e": "mocha --timeout 10000 --retries 10 --require ts-node/register --extension ts e2e"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -21,13 +21,17 @@
|
|||
},
|
||||
"homepage": "https://github.com/ueokande/vim-vixen",
|
||||
"devDependencies": {
|
||||
"@types/assert": "^1.4.3",
|
||||
"@types/chai": "^4.2.0",
|
||||
"@types/express": "^4.17.1",
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/node": "^12.7.5",
|
||||
"@types/prop-types": "^15.7.1",
|
||||
"@types/react": "^16.9.2",
|
||||
"@types/react-dom": "^16.9.0",
|
||||
"@types/react-redux": "^7.1.2",
|
||||
"@types/redux-promise": "^0.5.28",
|
||||
"@types/selenium-webdriver": "^4.0.2",
|
||||
"@types/sinon": "^7.0.13",
|
||||
"@typescript-eslint/eslint-plugin": "^2.0.0",
|
||||
"@typescript-eslint/parser": "^2.0.0",
|
||||
|
@ -35,6 +39,7 @@
|
|||
"css-loader": "^3.2.0",
|
||||
"eslint": "^6.2.2",
|
||||
"eslint-plugin-react": "^7.14.3",
|
||||
"express": "^4.17.1",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"jszip": "^3.2.2",
|
||||
|
@ -46,7 +51,7 @@
|
|||
"karma-sinon": "^1.0.5",
|
||||
"karma-sourcemap-loader": "^0.3.7",
|
||||
"karma-webpack": "^4.0.2",
|
||||
"lanthan": "git+https://github.com/ueokande/lanthan.git#master",
|
||||
"lanthan": "0.0.2",
|
||||
"mocha": "^6.2.0",
|
||||
"node-sass": "^4.12.0",
|
||||
"react": "^16.9.0",
|
||||
|
@ -62,6 +67,7 @@
|
|||
"sinon-chrome": "^3.0.1",
|
||||
"style-loader": "^1.0.0",
|
||||
"ts-loader": "^6.0.4",
|
||||
"ts-node": "^8.4.1",
|
||||
"tsyringe": "^3.3.0",
|
||||
"typescript": "^3.6.2",
|
||||
"web-ext-types": "^3.2.1",
|
||||
|
|
Reference in a new issue