Merge pull request #564 from ueokande/lanthan-integration-test

Use lanthan to do E2E testing
jh-changes
Shin'ya Ueoka 6 years ago committed by GitHub
commit 640ac38fb6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 48
      QA.md
  2. 67
      e2e/command_addbookmark.test.js
  3. 203
      e2e/command_bdelete.test.js
  4. 202
      e2e/command_buffer.test.js
  5. 149
      e2e/command_open.test.js
  6. 125
      e2e/command_quit.test.js
  7. 160
      e2e/command_tabopen.test.js
  8. 172
      e2e/command_winopen.test.js
  9. 125
      e2e/console.test.js
  10. 2
      e2e/mark.test.js
  11. 111
      e2e/navigate.test.js
  12. 2
      e2e/scroll.test.js
  13. 85
      e2e/settings.js
  14. 2
      e2e/tab.test.js
  15. 19
      e2e/zoom.test.js
  16. 20028
      package-lock.json
  17. 7
      package.json
  18. 11
      src/background/index.js
  19. 6
      src/background/infrastructures/ContentMessageListener.js
  20. 4
      src/settings/actions/setting.js
  21. 1
      src/shared/messages.js

48
QA.md

@ -8,19 +8,6 @@ Test operations with default key maps.
The behaviors of the console are tested in [Console section](#consoles).
- [ ] <kbd>:</kbd>: open empty console
- [ ] <kbd>o</kbd>, <kbd>t</kbd>, <kbd>w</kbd>: open a console with `open`, `tabopen`, `winopen`
- [ ] <kbd>O</kbd>, <kbd>T</kbd>, <kbd>W</kbd>: open a console with `open`, `tabopen`, `winopen` and current URL
- [ ] <kbd>b</kbd>: open a console with `buffer`
- [ ] <kbd>a</kbd>: open a console with `addbookmark` and the current page's title
#### Tabs
- [ ] <kbd>r</kbd>: reload current tab
- [ ] <kbd>R</kbd>: reload current tab without cache
- [ ] <kbd>g</kbd><kbd>h</kbd>: open start page on current tab
- [ ] <kbd>g</kbd><kbd>H</kbd>: open start page to new tab
#### Misc
- [ ] <kbd>y</kbd>: yank current URL and show a message
@ -50,41 +37,6 @@ The behaviors of the console are tested in [Console section](#consoles).
#### Exec a command
- [ ] `<EMPTY>`: do nothing
<br>
- [ ] `open an apple`: search with keywords "an apple" by default search engine (google)
- [ ] `open github.com`: open github.com
- [ ] `open https://github.com`: open github.com
- [ ] `open yahoo an apple`: search with keywords "an apple" by yahoo.com
- [ ] `open yahoo`: search with empty keywords; yahoo redirects to top page
- [ ] `open`: open default search engine
<br>
- [ ] `tabopen`: do above tests replaced `open` with `tabopen`, and verify the page is opened in new tab
- [ ] `winopen`: do above tests replaced `open` with `winopen`, and verify the page is opened in new window
<br>
- [ ] `buffer`: do nothing
- [ ] `buffer <title>`, `buffer <url>`: select tab which has an title matched with
- [ ] `buffer 1`: select leftmost tab
- [ ] `buffer 0`, `buffer <a number more than count of tabs>`: shows an error
- [ ] select tabs rotationally when more than two tabs are matched
- [ ] `buffer %`: select current tab (nothing to do)
- [ ] `buffer #`: select last selected tab
<br>
- [ ] `addbookmark` creates a bookmark
<br>
- [ ] `q`, `quit`: close current tab
- [ ] `qa`, `quitall`: close all tabs
- [ ] `bdelete`: delete a not-pinned tab matches with keywords
- [ ] `bdelete`: show errors no-tabs or more than 1 tabs matched
- [ ] `bdelete`: can not delete pinned tab
- [ ] `bdelete!`: delete a tab matches with keywords
- [ ] `bdelete!`: delete a pinned tab matches with keywords
- [ ] `bdeletes`: delete tabs with matched with keywords excluding pinned
- [ ] `bdeletes!`: delete tabs with matched with keywords including pinned
### Completions

@ -0,0 +1,67 @@
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`);
});
});
});

@ -0,0 +1,203 @@
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);
});
});
});

@ -0,0 +1,202 @@
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);
});
});
});

@ -0,0 +1,149 @@
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/')
});
});
});

@ -0,0 +1,125 @@
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)
});
});
});

@ -0,0 +1,160 @@
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/')
});
});
});

@ -0,0 +1,172 @@
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/')
});
});
});

@ -0,0 +1,125 @@
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!`);
});
});

@ -29,7 +29,7 @@ describe("mark test", () => {
http = newApp().listen(port);
firefox = await lanthan.firefox();
await firefox.session.installAddon(path.join(__dirname, '..'));
await firefox.session.installAddonFromPath(path.join(__dirname, '..'));
session = firefox.session;
browser = firefox.browser;
});

@ -24,6 +24,15 @@ const newApp = () => {
</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>
@ -34,7 +43,7 @@ const newApp = () => {
return app;
};
describe("zoom test", () => {
describe("navigate test", () => {
const port = 12321;
let http;
@ -45,8 +54,12 @@ describe("zoom test", () => {
before(async() => {
http = newApp().listen(port);
firefox = await lanthan.firefox();
await firefox.session.installAddon(path.join(__dirname, '..'));
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;
});
@ -58,16 +71,25 @@ describe("zoom test", () => {
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`);
@ -75,11 +97,13 @@ describe("zoom test", () => {
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`);
@ -162,6 +186,85 @@ describe("zoom test", () => {
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);
});
});
});
});

@ -28,7 +28,7 @@ describe("scroll test", () => {
http = newApp().listen(port);
firefox = await lanthan.firefox();
await firefox.session.installAddon(path.join(__dirname, '..'));
await firefox.session.installAddonFromPath(path.join(__dirname, '..'));
session = firefox.session;
});

@ -0,0 +1,85 @@
module.exports = {
source: 'json',
json: `{
"keymaps": {
"0": { "type": "scroll.home" },
":": { "type": "command.show" },
"o": { "type": "command.show.open", "alter": false },
"O": { "type": "command.show.open", "alter": true },
"t": { "type": "command.show.tabopen", "alter": false },
"T": { "type": "command.show.tabopen", "alter": true },
"w": { "type": "command.show.winopen", "alter": false },
"W": { "type": "command.show.winopen", "alter": true },
"b": { "type": "command.show.buffer" },
"a": { "type": "command.show.addbookmark", "alter": true },
"k": { "type": "scroll.vertically", "count": -1 },
"j": { "type": "scroll.vertically", "count": 1 },
"h": { "type": "scroll.horizonally", "count": -1 },
"l": { "type": "scroll.horizonally", "count": 1 },
"<C-U>": { "type": "scroll.pages", "count": -0.5 },
"<C-D>": { "type": "scroll.pages", "count": 0.5 },
"<C-B>": { "type": "scroll.pages", "count": -1 },
"<C-F>": { "type": "scroll.pages", "count": 1 },
"gg": { "type": "scroll.top" },
"G": { "type": "scroll.bottom" },
"$": { "type": "scroll.end" },
"d": { "type": "tabs.close" },
"D": { "type": "tabs.close.right" },
"!d": { "type": "tabs.close.force" },
"u": { "type": "tabs.reopen" },
"K": { "type": "tabs.prev", "count": 1 },
"J": { "type": "tabs.next", "count": 1 },
"gT": { "type": "tabs.prev", "count": 1 },
"gt": { "type": "tabs.next", "count": 1 },
"g0": { "type": "tabs.first" },
"g$": { "type": "tabs.last" },
"<C-6>": { "type": "tabs.prevsel" },
"r": { "type": "tabs.reload", "cache": false },
"R": { "type": "tabs.reload", "cache": true },
"zp": { "type": "tabs.pin.toggle" },
"zd": { "type": "tabs.duplicate" },
"zi": { "type": "zoom.in" },
"zo": { "type": "zoom.out" },
"zz": { "type": "zoom.neutral" },
"f": { "type": "follow.start", "newTab": false },
"F": { "type": "follow.start", "newTab": true, "background": false },
"m": { "type": "mark.set.prefix" },
"'": { "type": "mark.jump.prefix" },
"H": { "type": "navigate.history.prev" },
"L": { "type": "navigate.history.next" },
"[[": { "type": "navigate.link.prev" },
"]]": { "type": "navigate.link.next" },
"gu": { "type": "navigate.parent" },
"gU": { "type": "navigate.root" },
"gi": { "type": "focus.input" },
"gf": { "type": "page.source" },
"gh": { "type": "page.home" },
"gH": { "type": "page.home", "newTab": true },
"y": { "type": "urls.yank" },
"p": { "type": "urls.paste", "newTab": false },
"P": { "type": "urls.paste", "newTab": true },
"/": { "type": "find.start" },
"n": { "type": "find.next" },
"N": { "type": "find.prev" },
"<S-Esc>": { "type": "addon.toggle.enabled" }
},
"search": {
"default": "google",
"engines": {
"google": "http://127.0.0.1:12321/google?q={}",
"yahoo": "http://127.0.0.1:12321/yahoo?q={}",
"bing": "http://127.0.0.1:12321/bind?q={}",
"duckduckgo": "http://127.0.0.1:12321/duplicate?q={}",
"twitter": "http://127.0.0.1:12321/twitter?q={}",
"wikipedia": "http://127.0.0.1:12321/wikipedia?q={}"
}
},
"properties": {
"hintchars": "abcdefghijklmnopqrstuvwxyz",
"smoothscroll": false,
"complete": "sbh"
},
"blacklist": [
]
}`,
}

@ -28,7 +28,7 @@ describe("tab test", () => {
before(async() => {
firefox = await lanthan.firefox();
await firefox.session.installAddon(path.join(__dirname, '..'));
await firefox.session.installAddonFromPath(path.join(__dirname, '..'));
session = firefox.session;
browser = firefox.browser;
http = newApp().listen(port);

@ -6,20 +6,8 @@ const eventually = require('./eventually');
const Key = lanthan.Key;
const newApp = () => {
let app = express();
app.get('/', (req, res) => {
res.send(`<!DOCTYPEhtml>
<html lang="en">
</html">`);
});
return app;
};
describe("zoom test", () => {
const port = 12321;
let http;
let firefox;
let session;
let browser;
@ -27,10 +15,8 @@ describe("zoom test", () => {
let body;
before(async() => {
http = newApp().listen(port);
firefox = await lanthan.firefox();
await firefox.session.installAddon(path.join(__dirname, '..'));
await firefox.session.installAddonFromPath(path.join(__dirname, '..'));
session = firefox.session;
browser = firefox.browser;
tab = (await browser.tabs.query({}))[0]
@ -40,11 +26,10 @@ describe("zoom test", () => {
if (firefox) {
await firefox.close();
}
http.close();
});
beforeEach(async() => {
await session.navigateTo(`http://127.0.0.1:${port}`);
await session.navigateTo('about:blank');
body = await session.findElementByCSS('body');
});

20028
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -7,7 +7,7 @@
"package": "npm run build && script/package.sh",
"lint": "eslint --ext .jsx,.js src",
"test": "karma start",
"test:e2e": "mocha --timeout 5000 e2e"
"test:e2e": "mocha --timeout 8000 e2e"
},
"repository": {
"type": "git",
@ -48,9 +48,8 @@
"sass-loader": "^7.1.0",
"sinon-chrome": "^2.3.2",
"style-loader": "^0.23.1",
"web-ext": "github:ueokande/web-ext#patched-3.0.0",
"webextensions-api-fake": "^0.5.1",
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3"
"webpack": "^4.30.0",
"webpack-cli": "^3.3.0"
}
}

@ -2,7 +2,8 @@ import ContentMessageListener from './infrastructures/ContentMessageListener';
import SettingController from './controllers/SettingController';
import VersionController from './controllers/VersionController';
new SettingController().reload();
let settingController = new SettingController();
settingController.reload();
browser.runtime.onInstalled.addListener((details) => {
if (details.reason !== 'install' && details.reason !== 'update') {
@ -12,3 +13,11 @@ browser.runtime.onInstalled.addListener((details) => {
});
new ContentMessageListener().run();
browser.storage.onChanged.addListener((changes, area) => {
if (area !== 'local') {
return;
}
if (changes.settings) {
settingController.reload();
}
});

@ -51,8 +51,6 @@ export default class ContentMessageListener {
return this.onConsoleEnterCommand(message.text);
case messages.SETTINGS_QUERY:
return this.onSettingsQuery();
case messages.SETTINGS_RELOAD:
return this.onSettingsReload();
case messages.FIND_GET_KEYWORD:
return this.onFindGetKeyword();
case messages.FIND_SET_KEYWORD:
@ -87,10 +85,6 @@ export default class ContentMessageListener {
return this.settingController.getSetting();
}
onSettingsReload() {
return this.settingController.reload();
}
onFindGetKeyword() {
return this.findController.getKeyword();
}

@ -1,5 +1,4 @@
import actions from 'settings/actions';
import messages from 'shared/messages';
import * as validator from 'shared/settings/validator';
import KeymapsForm from '../components/form/keymaps-form';
import * as settingsValues from 'shared/settings/values';
@ -24,9 +23,6 @@ const save = async(settings) => {
};
}
await settingsStorage.save(settings);
await browser.runtime.sendMessage({
type: messages.SETTINGS_RELOAD
});
return set(settings);
};

@ -59,7 +59,6 @@ export default {
OPEN_URL: 'open.url',
SETTINGS_RELOAD: 'settings.reload',
SETTINGS_CHANGED: 'settings.changed',
SETTINGS_QUERY: 'settings.query',