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