diff options
Diffstat (limited to 'e2e')
33 files changed, 746 insertions, 1279 deletions
diff --git a/e2e/ambassador/manifest.json b/e2e/ambassador/manifest.json deleted file mode 100644 index d2253f6..0000000 --- a/e2e/ambassador/manifest.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "manifest_version": 2, - "name": "ambassador", - "description": "WebExtension test helper", - "version": "0.1", - "content_scripts": [ - { - "all_frames": true, - "matches": [ "<all_urls>" ], - "js": [ "build/content.js" ], - "run_at": "document_start", - "match_about_blank": true - } - ], - "background": { - "scripts": [ - "build/background.js" - ] - }, - "permissions": [ - "history", - "sessions", - "storage", - "tabs", - "clipboardRead", - "activeTab" - ] -} diff --git a/e2e/ambassador/src/background/index.js b/e2e/ambassador/src/background/index.js deleted file mode 100644 index ce21dc8..0000000 --- a/e2e/ambassador/src/background/index.js +++ /dev/null @@ -1,49 +0,0 @@ -import { - WINDOWS_CREATE, WINDOWS_REMOVE, WINDOWS_GET, - TABS_CREATE, TABS_SELECT_AT, TABS_GET, TABS_UPDATE, TABS_REMOVE, - TABS_GET_ZOOM, TABS_SET_ZOOM, - EVENT_KEYPRESS, EVENT_KEYDOWN, EVENT_KEYUP, - SCROLL_GET, SCROLL_SET, -} from '../shared/messages'; -import * as tabs from './tabs'; -import { receiveContentMessage } from './ipc'; - -receiveContentMessage((message) => { - switch (message.type) { - case WINDOWS_CREATE: - return browser.windows.create({ url: message.url }); - case WINDOWS_REMOVE: - return browser.windows.remove(message.windowId); - case WINDOWS_GET: - return browser.windows.get(message.windowId, { populate: true }); - case TABS_CREATE: - return tabs.create({ - url: message.url, - windowId: message.windowId, - }); - case TABS_SELECT_AT: - return tabs.selectAt({ - windowId: message.windowId, - index: message.index, - }); - case TABS_GET: - return browser.tabs.get(message.tabId); - case TABS_UPDATE: - return browser.tabs.update(message.tabId, message.properties); - case TABS_REMOVE: - return browser.tabs.remove(message.tabId); - case TABS_GET_ZOOM: - return browser.tabs.getZoom(message.tabId); - case TABS_SET_ZOOM: - return browser.tabs.setZoom(message.tabId, message.factor); - case EVENT_KEYPRESS: - case EVENT_KEYDOWN: - case EVENT_KEYUP: - case SCROLL_GET: - case SCROLL_SET: - return browser.tabs.sendMessage( - message.tabId, - message - ); - } -}); diff --git a/e2e/ambassador/src/background/ipc.js b/e2e/ambassador/src/background/ipc.js deleted file mode 100644 index 95d2164..0000000 --- a/e2e/ambassador/src/background/ipc.js +++ /dev/null @@ -1,7 +0,0 @@ -const receiveContentMessage = (func) => { - browser.runtime.onMessage.addListener((message) => { - return func(message); - }); -}; - -export { receiveContentMessage }; diff --git a/e2e/ambassador/src/background/tabs.js b/e2e/ambassador/src/background/tabs.js deleted file mode 100644 index 5594134..0000000 --- a/e2e/ambassador/src/background/tabs.js +++ /dev/null @@ -1,28 +0,0 @@ -const create = (props = {}) => { - return new Promise((resolve) => { - browser.tabs.create(props).then((createdTab) => { - let callback = (tabId, changeInfo, tab) => { - if (tab.url !== 'about:blank' && tabId === createdTab.id && - changeInfo.status === 'complete') { - browser.tabs.onUpdated.removeListener(callback); - - // wait for 50 milliseconds to ensure plugin loaded; - setTimeout(() => resolve(tab), 50); - } - }; - browser.tabs.onUpdated.addListener(callback); - }); - }); -}; - -const selectAt = (props = {}) => { - return browser.tabs.query({ windowId: props.windowId }).then((tabs) => { - let target = tabs[props.index]; - return browser.tabs.update(target.id, { active: true }); - }); -}; - - -export { - create, selectAt -}; diff --git a/e2e/ambassador/src/client/ipc.js b/e2e/ambassador/src/client/ipc.js deleted file mode 100644 index 9f232ea..0000000 --- a/e2e/ambassador/src/client/ipc.js +++ /dev/null @@ -1,29 +0,0 @@ -import { METHOD_REQUEST, METHOD_RESPONSE } from '../shared/messages'; - -const generateId = () => { - return Math.random().toString(); -}; - -const send = (message) => { - return new Promise((resolve) => { - let id = generateId(); - let callback = (e) => { - let packet = e.data; - if (e.source !== window || packet.method !== METHOD_RESPONSE || - packet.id !== id) { - return; - } - window.removeEventListener('message', callback); - resolve(packet.message); - }; - window.addEventListener('message', callback); - - window.postMessage({ - id, - method: METHOD_REQUEST, - message - }, window.origin); - }); -}; - -export { send }; diff --git a/e2e/ambassador/src/client/keys.js b/e2e/ambassador/src/client/keys.js deleted file mode 100644 index 6b36c23..0000000 --- a/e2e/ambassador/src/client/keys.js +++ /dev/null @@ -1,28 +0,0 @@ -import { EVENT_KEYPRESS, EVENT_KEYDOWN, EVENT_KEYUP } from '../shared/messages'; -import * as ipc from './ipc'; - -const NEUTRAL_MODIFIERS = { shiftKey: false, altKey: false, ctrlKey: false }; - -const press = (tabId, key, modifiers = NEUTRAL_MODIFIERS) => { - return ipc.send({ ...modifiers, - type: EVENT_KEYPRESS, - tabId, - key, }); -}; - -const down = (tabId, key, modifiers = NEUTRAL_MODIFIERS) => { - return ipc.send({ modifiers, - type: EVENT_KEYDOWN, - tabId, - key, }); -}; - - -const up = (tabId, key, modifiers = NEUTRAL_MODIFIERS) => { - return ipc.send({ modifiers, - type: EVENT_KEYUP, - tabId, - key, }); -}; - -export { press, down, up }; diff --git a/e2e/ambassador/src/client/scrolls.js b/e2e/ambassador/src/client/scrolls.js deleted file mode 100644 index f8f82e9..0000000 --- a/e2e/ambassador/src/client/scrolls.js +++ /dev/null @@ -1,20 +0,0 @@ -import { SCROLL_GET, SCROLL_SET } from '../shared/messages'; -import * as ipc from './ipc'; - -const get = (tabId) => { - return ipc.send({ - type: SCROLL_GET, - tabId, - }); -}; - -const set = (tabId, x, y) => { - return ipc.send({ - type: SCROLL_SET, - tabId, - x, - y, - }); -}; - -export { get, set }; diff --git a/e2e/ambassador/src/client/tabs.js b/e2e/ambassador/src/client/tabs.js deleted file mode 100644 index d0cd578..0000000 --- a/e2e/ambassador/src/client/tabs.js +++ /dev/null @@ -1,60 +0,0 @@ -import { - TABS_CREATE, TABS_SELECT_AT, TABS_GET, TABS_UPDATE, TABS_REMOVE, - TABS_GET_ZOOM, TABS_SET_ZOOM, -} from '../shared/messages'; -import * as ipc from './ipc'; - -const create = (windowId, url) => { - return ipc.send({ - type: TABS_CREATE, - windowId, - url, - }); -}; - -const selectAt = (windowId, index) => { - return ipc.send({ - type: TABS_SELECT_AT, - windowId, - index, - }); -}; - -const get = (tabId) => { - return ipc.send({ - type: TABS_GET, - tabId, - }); -}; - -const update = (tabId, properties) => { - return ipc.send({ - type: TABS_UPDATE, - tabId, - properties, - }); -}; - -const remove = (tabId) => { - return ipc.send({ - type: TABS_REMOVE, - tabId - }); -}; - -const getZoom = (tabId) => { - return ipc.send({ - tabId, - type: TABS_GET_ZOOM, - }); -}; - -const setZoom = (tabId, factor) => { - return ipc.send({ - type: TABS_SET_ZOOM, - tabId, - factor, - }); -}; - -export { create, selectAt, get, update, remove, getZoom, setZoom }; diff --git a/e2e/ambassador/src/client/windows.js b/e2e/ambassador/src/client/windows.js deleted file mode 100644 index f92405a..0000000 --- a/e2e/ambassador/src/client/windows.js +++ /dev/null @@ -1,27 +0,0 @@ -import { - WINDOWS_CREATE, WINDOWS_REMOVE, WINDOWS_GET -} from '../shared/messages'; -import * as ipc from './ipc'; - -const create = (url) => { - return ipc.send({ - type: WINDOWS_CREATE, - url, - }); -}; - -const remove = (windowId) => { - return ipc.send({ - type: WINDOWS_REMOVE, - windowId, - }); -}; - -const get = (windowId) => { - return ipc.send({ - type: WINDOWS_GET, - windowId, - }); -}; - -export { create, remove, get }; diff --git a/e2e/ambassador/src/content/events.js b/e2e/ambassador/src/content/events.js deleted file mode 100644 index 1e45909..0000000 --- a/e2e/ambassador/src/content/events.js +++ /dev/null @@ -1,31 +0,0 @@ -const keypress = (opts) => { - let event = new KeyboardEvent('keypress', { - key: opts.key, - altKey: opts.altKey, - shiftKey: opts.shiftKey, - ctrlKey: opts.ctrlKey - }); - document.body.dispatchEvent(event); -}; - -const keydown = (opts) => { - let event = new KeyboardEvent('keydown', { - key: opts.key, - altKey: opts.altKey, - shiftKey: opts.shiftKey, - ctrlKey: opts.ctrlKey - }); - document.body.dispatchEvent(event); -}; - -const keyup = (opts) => { - let event = new KeyboardEvent('keyup', { - key: opts.key, - altKey: opts.altKey, - shiftKey: opts.shiftKey, - ctrlKey: opts.ctrlKey - }); - document.body.dispatchEvent(event); -}; - -export { keypress, keydown, keyup }; diff --git a/e2e/ambassador/src/content/index.js b/e2e/ambassador/src/content/index.js deleted file mode 100644 index fd19136..0000000 --- a/e2e/ambassador/src/content/index.js +++ /dev/null @@ -1,30 +0,0 @@ -import { - EVENT_KEYPRESS, EVENT_KEYDOWN, EVENT_KEYUP, - SCROLL_GET, SCROLL_SET, -} from '../shared/messages'; -import * as ipc from './ipc'; -import * as events from './events'; -import * as scrolls from './scrolls'; - -ipc.receivePageMessage((message) => { - return ipc.sendToBackground(message); -}); - -ipc.receiveBackgroundMesssage((message) => { - switch (message.type) { - case EVENT_KEYPRESS: - events.keypress(message); - break; - case EVENT_KEYDOWN: - events.keydown(message); - break; - case EVENT_KEYUP: - events.keyup(message); - break; - case SCROLL_GET: - return Promise.resolve(scrolls.get()); - case SCROLL_SET: - return Promise.resolve(scrolls.set(message.x, message.y)); - } - return Promise.resolve({}); -}); diff --git a/e2e/ambassador/src/content/ipc.js b/e2e/ambassador/src/content/ipc.js deleted file mode 100644 index 917623c..0000000 --- a/e2e/ambassador/src/content/ipc.js +++ /dev/null @@ -1,40 +0,0 @@ -import { METHOD_REQUEST, METHOD_RESPONSE } from '../shared/messages'; - -const sendToBackground = (message) => { - return browser.runtime.sendMessage(message); -}; - -const receiveBackgroundMesssage = (func) => { - return browser.runtime.onMessage.addListener((message) => { - return Promise.resolve(func(message)); - }); -}; - -const receivePageMessage = (func) => { - window.addEventListener('message', (e) => { - let packet = e.data; - if (e.origin !== window.origin || packet.method !== METHOD_REQUEST) { - return; - } - - let resp = { - id: packet.id, - method: METHOD_RESPONSE, - }; - let respMessage = func(packet.message); - if (respMessage instanceof Promise) { - return respMessage.then((data) => { - resp.message = data; - e.source.postMessage(resp, e.origin); - }); - } else if (respMessage) { - resp.message = respMessage; - } - e.source.postMessage(resp, e.origin); - }); -}; - -export { - sendToBackground, receiveBackgroundMesssage, - receivePageMessage, -}; diff --git a/e2e/ambassador/src/content/scrolls.js b/e2e/ambassador/src/content/scrolls.js deleted file mode 100644 index 4227cf7..0000000 --- a/e2e/ambassador/src/content/scrolls.js +++ /dev/null @@ -1,20 +0,0 @@ -const get = () => { - let element = document.documentElement; - return { - xMax: element.scrollWidth - element.clientWidth, - yMax: element.scrollHeight - element.clientHeight, - x: element.scrollLeft, - y: element.scrollTop, - frameWidth: element.clientWidth, - frameHeight: element.clientHeight, - }; -}; - -const set = (x, y) => { - let element = document.documentElement; - element.scrollLeft = x; - element.scrollTop = y; - return get(); -}; - -export { get, set }; diff --git a/e2e/ambassador/src/shared/messages.js b/e2e/ambassador/src/shared/messages.js deleted file mode 100644 index 35c41d7..0000000 --- a/e2e/ambassador/src/shared/messages.js +++ /dev/null @@ -1,40 +0,0 @@ -const METHOD_REQUEST = 'request'; -const METHOD_RESPONSE = 'response'; -const WINDOWS_CREATE = 'windows.create'; -const WINDOWS_REMOVE = 'windows.remove'; -const WINDOWS_GET = 'windows.get'; -const TABS_CREATE = 'tabs.create'; -const TABS_SELECT_AT = 'tabs.selectAt'; -const TABS_GET = 'tabs.get'; -const TABS_UPDATE = 'tabs.update'; -const TABS_REMOVE = 'tabs.remove'; -const TABS_GET_ZOOM = 'tabs.get.zoom'; -const TABS_SET_ZOOM = 'tabs.set.zoom'; -const EVENT_KEYPRESS = 'event.keypress'; -const EVENT_KEYDOWN = 'event.keydown'; -const EVENT_KEYUP = 'event.keyup'; -const SCROLL_GET = 'scroll.get'; -const SCROLL_SET = 'scroll.set'; - -export { - METHOD_REQUEST, - METHOD_RESPONSE, - - WINDOWS_CREATE, - WINDOWS_REMOVE, - WINDOWS_GET, - - TABS_GET, - TABS_UPDATE, - TABS_CREATE, - TABS_SELECT_AT, - TABS_GET_ZOOM, - TABS_SET_ZOOM, - TABS_REMOVE, - - EVENT_KEYPRESS, - EVENT_KEYDOWN, - EVENT_KEYUP, - SCROLL_GET, - SCROLL_SET, -}; diff --git a/e2e/ambassador/webpack.config.js b/e2e/ambassador/webpack.config.js deleted file mode 100644 index d292317..0000000 --- a/e2e/ambassador/webpack.config.js +++ /dev/null @@ -1,24 +0,0 @@ -const path = require('path'); - -const src = path.resolve(__dirname, 'src'); -const dist = path.resolve(__dirname, 'build'); - -config = { - entry: { - content: path.join(src, 'content'), - background: path.join(src, 'background') - }, - - output: { - path: dist, - filename: '[name].js' - }, - - resolve: { - extensions: [ '.js' ], - modules: [path.join(__dirname, 'src'), 'node_modules'] - } -}; - -module.exports = config - diff --git a/e2e/contents/follow.test.js b/e2e/contents/follow.test.js deleted file mode 100644 index f78780b..0000000 --- a/e2e/contents/follow.test.js +++ /dev/null @@ -1,83 +0,0 @@ -import * as windows from "../ambassador/src/client/windows"; -import * as tabs from "../ambassador/src/client/tabs"; -import * as keys from "../ambassador/src/client/keys"; -import { CLIENT_URL } from '../web-server/url'; - -describe("tab test", () => { - let targetWindow; - - beforeEach(async () => { - targetWindow = await windows.create(CLIENT_URL); - }); - - afterEach(async () => { - await windows.remove(targetWindow.id); - });return - - it('follows link by `f`', async() => { - let tab = await tabs.create(targetWindow.id, CLIENT_URL + '/follow'); - await keys.press(tab.id, 'f'); - await new Promise(resolve => { setTimeout(() => resolve(), 10) }); - await keys.press(tab.id, 'a'); - await new Promise(resolve => { setTimeout(() => resolve(), 10) }); - - tab = tabs.get(tab.id); - expect(tab.url).to.be.equal(CLIENT_URL + '/follow#a'); - }); - - it('follows link into new tab by `F`', async () => { - let tab = await tabs.create(targetWindow.id, CLIENT_URL + '/follow'); - await keys.press(tab.id, 'F', { shiftKey: true }); - await new Promise(resolve => { setTimeout(() => resolve(), 10) }); - await keys.press(tab.id, 'a'); - await new Promise(resolve => { setTimeout(() => resolve(), 500) }); - - let win = await windows.get(targetWindow.id); - let urls = win.tabs.map(t => t.url); - expect(urls).to.have.lengthOf(3); - expect(urls).to.include(CLIENT_URL + '/'); - expect(urls).to.include(CLIENT_URL + '/follow'); - expect(urls).to.include(CLIENT_URL + '/follow#a'); - }); - - it('follows link with target=_blank into new tab by `f`', async () => { - let tab = await tabs.create(targetWindow.id, CLIENT_URL + '/follow'); - await keys.press(tab.id, 'f'); - await new Promise(resolve => { setTimeout(() => resolve(), 10) }); - await keys.press(tab.id, 'b'); - await new Promise(resolve => { setTimeout(() => resolve(), 500) }); - - let win = await windows.get(targetWindow.id); - let urls = win.tabs.map(t => t.url); - expect(urls).to.have.lengthOf(3); - expect(urls).to.include(CLIENT_URL + '/'); - expect(urls).to.include(CLIENT_URL + '/follow'); - expect(urls).to.include(CLIENT_URL + '/follow#external'); - }); - - it('follows link with target=_blank into new tab by `F`', async () => { - let tab = await tabs.create(targetWindow.id, CLIENT_URL + '/follow'); - await keys.press(tab.id, 'F', { shiftKey: true }); - await new Promise(resolve => { setTimeout(() => resolve(), 10) }); - await keys.press(tab.id, 'b'); - await new Promise(resolve => { setTimeout(() => resolve(), 500) }); - - let win = await windows.get(targetWindow.id); - let urls = win.tabs.map(t => t.url); - expect(urls).to.have.lengthOf(3); - expect(urls).to.include(CLIENT_URL + '/'); - expect(urls).to.include(CLIENT_URL + '/follow'); - expect(urls).to.include(CLIENT_URL + '/follow#external'); - }); - - it('follows area by `F`', async () => { - let tab = await tabs.create(targetWindow.id, CLIENT_URL + '/follow'); - await keys.press(tab.id, 'f'); - await new Promise(resolve => { setTimeout(() => resolve(), 10) }); - await keys.press(tab.id, 'c'); - await new Promise(resolve => { setTimeout(() => resolve(), 10) }); - - tab = await tabs.get(tab.id); - expect(tab.url).to.be.equal(CLIENT_URL + '/follow#area'); - }); -}); diff --git a/e2e/contents/mark.test.js b/e2e/contents/mark.test.js deleted file mode 100644 index 85566bd..0000000 --- a/e2e/contents/mark.test.js +++ /dev/null @@ -1,71 +0,0 @@ -import * as windows from "../ambassador/src/client/windows"; -import * as tabs from "../ambassador/src/client/tabs"; -import * as keys from "../ambassador/src/client/keys"; -import * as scrolls from "../ambassador/src/client/scrolls"; -import { CLIENT_URL } from '../web-server/url'; - -describe("mark test", () => { - let targetWindow; - - before(async () => { - targetWindow = await windows.create(); - }); - - after(async () => { - await windows.remove(targetWindow.id); - }); - - it('set a local mark and jump to it', async () => { - let tab = await tabs.create(targetWindow.id, CLIENT_URL + '/mark#local'); - await scrolls.set(tab.id, 100, 100); - await keys.press(tab.id, 'm'); - await keys.press(tab.id, 'a'); - - await scrolls.set(tab.id, 200, 200); - await keys.press(tab.id, "'"); - await keys.press(tab.id, 'a'); - - let scroll = await scrolls.get(tab.id); - expect(scroll.x).to.be.equals(100); - expect(scroll.y).to.be.equals(100); - }); - - it('set a global mark and jump to it', async () => { - let tab1 = await tabs.create(targetWindow.id, CLIENT_URL + '/mark#global1'); - await scrolls.set(tab1.id, 100, 100); - await keys.press(tab1.id, 'm'); - await keys.press(tab1.id, 'A'); - await new Promise(resolve => { setTimeout(() => resolve(), 100) }); - await scrolls.set(tab1.id, 200, 200); - - let tab2 = await tabs.create(targetWindow.id, CLIENT_URL + '/mark#global2'); - await keys.press(tab2.id, "'"); - await keys.press(tab2.id, 'A'); - await new Promise(resolve => { setTimeout(() => resolve(), 100) }); - - tab1 = await tabs.get(tab1.id); - expect(tab1.active).to.be.true; - let scroll = await scrolls.get(tab1.id); - expect(scroll.x).to.be.equals(100); - expect(scroll.y).to.be.equals(100); - }); - - it('set a global mark and creates new tab from gone', async () => { - let tab1 = await tabs.create(targetWindow.id, CLIENT_URL + '/mark#gone'); - await scrolls.set(tab1.id, 100, 100); - await keys.press(tab1.id, 'm'); - await keys.press(tab1.id, 'A'); - await tabs.remove(tab1.id); - await new Promise(resolve => { setTimeout(() => resolve(), 100) }); - - let tab2 = await tabs.create(targetWindow.id, CLIENT_URL + '/mark#newtab'); - await keys.press(tab2.id, "'"); - await keys.press(tab2.id, 'A'); - await new Promise(resolve => { setTimeout(() => resolve(), 100) }); - - let win = await windows.get(targetWindow.id); - let found = win.tabs.find(tab => tab.url === CLIENT_URL + '/mark#gone') - expect(found).to.be.an('object'); - expect(found.id).to.not.equal(tab1.id); - }); -}); diff --git a/e2e/contents/navigate.test.js b/e2e/contents/navigate.test.js deleted file mode 100644 index 32ed423..0000000 --- a/e2e/contents/navigate.test.js +++ /dev/null @@ -1,102 +0,0 @@ -import * as windows from "../ambassador/src/client/windows"; -import * as tabs from "../ambassador/src/client/tabs"; -import * as keys from "../ambassador/src/client/keys"; -import * as scrolls from "../ambassador/src/client/scrolls"; -import { CLIENT_URL } from '../web-server/url'; - -describe("navigate test", () => { - let targetWindow; - - before(async () => { - targetWindow = await windows.create(); - await tabs.create(targetWindow.id, CLIENT_URL); - }); - - after(async () => { - await windows.remove(targetWindow.id); - }); - - it('goes to parent', async () => { - let tab = await tabs.create(targetWindow.id, CLIENT_URL + '/a/b/c'); - await keys.press(tab.id, 'g'); - await keys.press(tab.id, 'u'); - await new Promise((resolve) => setTimeout(resolve, 10)); - - tab = await tabs.get(tab.id); - expect(tab.url).to.be.equal(CLIENT_URL + '/a/b/'); - }); - - it('removes hash', async () => { - let tab = await tabs.create(targetWindow.id, CLIENT_URL + '/a/b/c#navigate'); - await keys.press(tab.id, 'g'); - await keys.press(tab.id, 'u'); - tab = await tabs.get(tab.id); - expect(tab.url).to.be.equal(CLIENT_URL + '/a/b/c#'); - }); - - it('goes to root', async () => { - let tab = await tabs.create(targetWindow.id, CLIENT_URL + '/a/b/c'); - await keys.press(tab.id, 'g'); - await keys.press(tab.id, 'U', { shiftKey: true }); - await new Promise((resolve) => setTimeout(resolve, 10)); - - tab = await tabs.get(tab.id); - expect(tab.url).to.be.equal(CLIENT_URL + '/'); - }); - - it('goes back and forward in history', async () => { - let tab = await tabs.create(targetWindow.id, CLIENT_URL + '/#navigate'); - await keys.press(tab.id, 'g'); - await keys.press(tab.id, 'u'); - await keys.press(tab.id, 'H', { shiftKey: true }); - await new Promise((resolve) => setTimeout(resolve, 10)); - - tab = await tabs.get(tab.id); - expect(tab.url, 'go back in history').to.be.equal(CLIENT_URL + '/#navigate'); - await new Promise((resolve) => setTimeout(resolve, 10)); - await keys.press(tab.id, 'L', { shiftKey: true }); - - tab = await tabs.get(tab.id); - expect(tab.url, 'go next in history').to.be.equal(CLIENT_URL + '/#'); - }); - - it('goes previous page by <a>', async () => { - let tab = await tabs.create(targetWindow.id, CLIENT_URL + '/a-pagenation?page=10'); - await keys.press(tab.id, '['); - await keys.press(tab.id, '['); - await new Promise((resolve) => setTimeout(resolve, 10)); - - tab = await tabs.get(tab.id); - expect(tab.url).to.be.equal(CLIENT_URL + '/a-pagenation?page=9'); - }) - - it('goes next page by <a>', async () => { - let tab = await tabs.create(targetWindow.id, CLIENT_URL + '/a-pagenation?page=10'); - await keys.press(tab.id, ']'); - await keys.press(tab.id, ']'); - await new Promise((resolve) => setTimeout(resolve, 100)); - - tab = await tabs.get(tab.id); - expect(tab.url).to.be.equal(CLIENT_URL + '/a-pagenation?page=11'); - }) - - it('goes previous page by <link>', async () => { - let tab = await tabs.create(targetWindow.id, CLIENT_URL + '/link-pagenation?page=10'); - await keys.press(tab.id, '['); - await keys.press(tab.id, '['); - await new Promise((resolve) => setTimeout(resolve, 10)); - - tab = await tabs.get(tab.id); - expect(tab.url).to.be.equal(CLIENT_URL + '/link-pagenation?page=9'); - }) - - it('goes next page by <link>', async () => { - let tab = await tabs.create(targetWindow.id, CLIENT_URL + '/link-pagenation?page=10'); - await keys.press(tab.id, ']'); - await keys.press(tab.id, ']'); - await new Promise((resolve) => setTimeout(resolve, 10)); - - tab = await tabs.get(tab.id); - expect(tab.url).to.be.equal(CLIENT_URL + '/link-pagenation?page=11'); - }) -}); diff --git a/e2e/contents/scroll.test.js b/e2e/contents/scroll.test.js deleted file mode 100644 index f364890..0000000 --- a/e2e/contents/scroll.test.js +++ /dev/null @@ -1,106 +0,0 @@ -import * as windows from "../ambassador/src/client/windows"; -import * as tabs from "../ambassador/src/client/tabs"; -import * as keys from "../ambassador/src/client/keys"; -import * as scrolls from "../ambassador/src/client/scrolls"; -import { CLIENT_URL } from '../web-server/url'; - -describe("scroll test", () => { - let targetWindow; - let targetTab; - - before(async () => { - targetWindow = await windows.create(); - targetTab = await tabs.create(targetWindow.id, CLIENT_URL + '/scroll'); - }); - - after(async () => { - await windows.remove(targetWindow.id); - }); - - it('scrolls up by k', async () => { - let before = await scrolls.set(targetTab.id, 100, 100); - await keys.press(targetTab.id, 'k'); - - let actual = await scrolls.get(targetTab.id); - expect(actual.y).to.be.lessThan(before.y); - }); - - it('scrolls down by j', async () => { - let before = await scrolls.set(targetTab.id, 100, 100); - await keys.press(targetTab.id, 'j'); - - let actual = await scrolls.get(targetTab.id); - expect(actual.y).to.be.greaterThan(before.y); - }); - - it('scrolls left by h', async () => { - let before = await scrolls.set(targetTab.id, 100, 100) - await keys.press(targetTab.id, 'h'); - - let actual = await scrolls.get(targetTab.id); - expect(actual.x).to.be.lessThan(before.x); - }); - - it('scrolls top by gg', async () => { - await scrolls.set(targetTab.id, 100, 100); - await keys.press(targetTab.id, 'g'); - await keys.press(targetTab.id, 'g'); - let actual = await scrolls.get(targetTab.id); - expect(actual.y).to.be.equals(0); - }); - - it('scrolls bottom by G', async () => { - await scrolls.set(targetTab.id, 100, 100); - await keys.press(targetTab.id, 'G', { shiftKey: true }); - - let actual = await scrolls.get(targetTab.id); - expect(actual.y).to.be.equals(actual.yMax); - }); - - it('scrolls bottom by 0', async () => { - await scrolls.set(targetTab.id, 100, 100); - await keys.press(targetTab.id, '0'); - - let actual = await scrolls.get(targetTab.id); - expect(actual.x).to.be.equals(0); - }); - - it('scrolls bottom by $', async () => { - await scrolls.set(targetTab.id, 100, 100); - await keys.press(targetTab.id, '$'); - - let actual = await scrolls.get(targetTab.id); - expect(actual.x).to.be.equals(actual.xMax); - }); - - it('scrolls bottom by <C-U>', async () => { - let before = await scrolls.set(targetTab.id, 5000, 5000); - await keys.press(targetTab.id, 'u', { ctrlKey: true }); - - let actual = await scrolls.get(targetTab.id); - expect(actual.y).to.closeTo(before.y - before.frameHeight / 2, 1); - }); - - it('scrolls bottom by <C-D>', async () => { - let before = await scrolls.set(targetTab.id, 5000, 5000); - await keys.press(targetTab.id, 'd', { ctrlKey: true }); - - let actual = await scrolls.get(targetTab.id); - expect(actual.y).to.closeTo(before.y + before.frameHeight / 2, 1); - }); - - it('scrolls bottom by <C-B>', async () => { - let before = await scrolls.set(targetTab.id, 5000, 5000); - await keys.press(targetTab.id, 'b', { ctrlKey: true }); - - let actual = await await scrolls.get(targetTab.id); - expect(actual.y).to.equals(before.y - before.frameHeight); - }); - - it('scrolls bottom by <C-F>', async () => { - let before = await scrolls.set(targetTab.id, 5000, 5000); - await keys.press(targetTab.id, 'f', { ctrlKey: true }); - let actual = await scrolls.get(targetTab.id); - expect(actual.y).to.equals(before.y + before.frameHeight); - }); -}); diff --git a/e2e/contents/tab.test.js b/e2e/contents/tab.test.js deleted file mode 100644 index 3c98dc9..0000000 --- a/e2e/contents/tab.test.js +++ /dev/null @@ -1,192 +0,0 @@ -import * as windows from "../ambassador/src/client/windows"; -import * as tabs from "../ambassador/src/client/tabs"; -import * as keys from "../ambassador/src/client/keys"; -import { CLIENT_URL } from '../web-server/url'; - -describe("tab test", () => { - let targetWindow; - - beforeEach(async () => { - targetWindow = await windows.create(CLIENT_URL); - }); - - afterEach(async () => { - await windows.remove(targetWindow.id); - }); - - it('deletes tab by d', async () => { - let tab = await tabs.create(targetWindow.id, CLIENT_URL); - let before = await windows.get(targetWindow.id); - await keys.press(tab.id, 'd'); - - let actual = await windows.get(targetWindow.id); - expect(actual.tabs).to.have.lengthOf(before.tabs.length - 1); - }); - - it('deletes tabs to the right by D', async () => { - let tab1 = await tabs.create(targetWindow.id, CLIENT_URL + '#1'); - await tabs.create(targetWindow.id, CLIENT_URL + '#2'); - await tabs.create(targetWindow.id, CLIENT_URL + '#3'); - - let before = await windows.get(targetWindow.id) - let tab = await tabs.selectAt(targetWindow.id, tab1.index) - await keys.press(tab.id, 'D', { shiftKey: true }); - - let actual = await windows.get(targetWindow.id); - expect(actual.tabs).to.have.lengthOf(before.tabs.length - 2); - }); - - it('duplicates tab by zd', async () => { - let tab = await tabs.create(targetWindow.id, CLIENT_URL); - let before = await windows.get(targetWindow.id) - await keys.press(tab.id, 'z'); - await keys.press(tab.id, 'd'); - - let actual = await windows.get(targetWindow.id); - expect(actual.tabs).to.have.lengthOf(before.tabs.length + 1); - }); - - it('makes pinned by zp', async () => { - let tab = await tabs.create(targetWindow.id, CLIENT_URL); - let before = await windows.get(targetWindow.id); - await keys.press(tab.id, 'z'); - await keys.press(tab.id, 'p'); - - let actual = await windows.get(targetWindow.id); - expect(actual.tabs[0].pinned).to.be.true; - }); - - it('selects previous tab by K', async () => { - await tabs.create(targetWindow.id, CLIENT_URL + '#1'); - await tabs.create(targetWindow.id, CLIENT_URL + '#2'); - await tabs.create(targetWindow.id, CLIENT_URL + '#3'); - let tab = await tabs.selectAt(targetWindow.id, 2); - await keys.press(tab.id, 'K', { shiftKey: true }); - - let win = await windows.get(targetWindow.id); - expect(win.tabs[1].active).to.be.true; - }); - - it('selects previous tab by K rotatory', async () => { - await tabs.create(targetWindow.id, CLIENT_URL + '#1'); - await tabs.create(targetWindow.id, CLIENT_URL + '#2'); - await tabs.create(targetWindow.id, CLIENT_URL + '#3'); - let tab = await tabs.selectAt(targetWindow.id, 0); - await keys.press(tab.id, 'K', { shiftKey: true }); - - let win = await windows.get(targetWindow.id); - expect(win.tabs[3].active).to.be.true; - }); - - it('selects next tab by J', async () => { - await tabs.create(targetWindow.id, CLIENT_URL + '#1'); - await tabs.create(targetWindow.id, CLIENT_URL + '#2'); - await tabs.create(targetWindow.id, CLIENT_URL + '#3'); - let tab = await tabs.selectAt(targetWindow.id, 2); - await keys.press(tab.id, 'J', { shiftKey: true }); - - let win = await windows.get(targetWindow.id); - expect(win.tabs[3].active).to.be.true; - }); - - it('selects previous tab by J rotatory', async () => { - await tabs.create(targetWindow.id, CLIENT_URL + '#1'); - await tabs.create(targetWindow.id, CLIENT_URL + '#2'); - await tabs.create(targetWindow.id, CLIENT_URL + '#3'); - let tab = await tabs.selectAt(targetWindow.id, 3); - await keys.press(tab.id, 'J', { shiftKey: true }); - - let win = await windows.get(targetWindow.id); - expect(win.tabs[0].active).to.be.true; - }); - - it('selects first tab by g0', async () => { - await tabs.create(targetWindow.id, CLIENT_URL + '#1'); - await tabs.create(targetWindow.id, CLIENT_URL + '#2'); - await tabs.create(targetWindow.id, CLIENT_URL + '#3'); - let tab = await tabs.selectAt(targetWindow.id, 2); - await keys.press(tab.id, 'g'); - await keys.press(tab.id, '0'); - - let win = await windows.get(targetWindow.id); - expect(win.tabs[0].active).to.be.true; - }); - - it('selects last tab by g$', async () => { - await tabs.create(targetWindow.id, CLIENT_URL + '#1'); - await tabs.create(targetWindow.id, CLIENT_URL + '#2'); - await tabs.create(targetWindow.id, CLIENT_URL + '#3'); - let tab = await tabs.selectAt(targetWindow.id, 2); - await keys.press(tab.id, 'g'); - await keys.press(tab.id, '$'); - - let win = await windows.get(targetWindow.id); - expect(win.tabs[3].active).to.be.true; - }); - - it('selects last selected tab by <C-6>', async () => { - await tabs.create(targetWindow.id, CLIENT_URL + '#1'); - await tabs.create(targetWindow.id, CLIENT_URL + '#2'); - await tabs.create(targetWindow.id, CLIENT_URL + '#3'); - await tabs.selectAt(targetWindow.id, 1); - let tab = await tabs.selectAt(targetWindow.id, 3); - await keys.press(tab.id, '6', { ctrlKey: true }); - - let win = await windows.get(targetWindow.id); - expect(win.tabs[1].active).to.be.true; - }); - - it('deletes tab by d', async () => { - let tab = await tabs.create(targetWindow.id, CLIENT_URL + '#1'); - await keys.press(tab.id, 'd'); - - let win = await windows.get(targetWindow.id); - expect(win.tabs).to.have.lengthOf(1); - }); - - it('reopen tab by u', async () => { - let tab = await tabs.create(targetWindow.id, CLIENT_URL + '#1'); - await keys.press(tab.id, 'd'); - - let win = await windows.get(targetWindow.id); - expect(win.tabs).to.have.lengthOf(1); - - await keys.press(win.tabs[0].id, 'u'); - await new Promise(resolve => setTimeout(resolve, 100)); - - win = await windows.get(targetWindow.id); - expect(win.tabs).to.have.lengthOf(2); - }); - - it('does not delete pinned tab by d', async () => { - let tab = await tabs.create(targetWindow.id, CLIENT_URL + '#1'); - tab = await tabs.update(tab.id, { pinned: true }); - await keys.press(tab.id, 'd'); - - let win = await windows.get(targetWindow.id); - expect(win.tabs).to.have.lengthOf(2); - }); - - it('deletes pinned tab by !d', async () => { - let tab = await tabs.create(targetWindow.id, CLIENT_URL + '#1'); - tab = await tabs.update(tab.id, { pinned: true }); - await keys.press(tab.id, '!'); - await keys.press(tab.id, 'd'); - - let win = await windows.get(targetWindow.id); - expect(win.tabs).to.have.lengthOf(1); - }); - - it('opens view-source by gf', async () => { - await new Promise(resolve => setTimeout(resolve, 100)); - let win = await windows.get(targetWindow.id); - let tab = win.tabs[0]; - await keys.press(tab.id, 'g'); - await keys.press(tab.id, 'f'); - await new Promise(resolve => setTimeout(resolve, 500)); - - win = await windows.get(targetWindow.id); - let urls = win.tabs.map((t) => t.url) - expect(urls).to.include.members([CLIENT_URL + '/', 'view-source:' + CLIENT_URL + '/']); - }); -}); diff --git a/e2e/contents/zoom.test.js b/e2e/contents/zoom.test.js deleted file mode 100644 index 74d4f56..0000000 --- a/e2e/contents/zoom.test.js +++ /dev/null @@ -1,53 +0,0 @@ -import * as windows from "../ambassador/src/client/windows"; -import * as tabs from "../ambassador/src/client/tabs"; -import * as keys from "../ambassador/src/client/keys"; -import { CLIENT_URL } from '../web-server/url'; - -describe("zoom test", () => { - let targetWindow; - let targetTab; - - before(async () => { - targetWindow = await windows.create(CLIENT_URL); - }); - - after(async () => { - await windows.remove(targetWindow.id); - }); - - beforeEach(async () => { - targetTab = await tabs.create(targetWindow.id, CLIENT_URL); - }); - - it('zooms-in by zi', async () => { - let before = await tabs.getZoom(targetTab.id); - await keys.press(targetTab.id, 'z'); - await keys.press(targetTab.id, 'i'); - await new Promise(resolve => setTimeout(resolve, 100)); - - let actual = await tabs.getZoom(targetTab.id); - expect(actual).to.be.greaterThan(before); - }); - - it('zooms-in by zo', async () => { - let before = await tabs.getZoom(targetTab.id); - await keys.press(targetTab.id, 'z'); - await keys.press(targetTab.id, 'o'); - await new Promise(resolve => setTimeout(resolve, 100)); - - let actual = await tabs.getZoom(targetTab.id); - expect(actual).to.be.lessThan(before); - }); - - it('zooms-in by zz', async () => { - await tabs.setZoom(targetTab.id, 1.5); - let before = await tabs.getZoom(targetTab.id); - await keys.press(targetTab.id, 'z'); - await keys.press(targetTab.id, 'z'); - await new Promise(resolve => setTimeout(resolve, 100)); - - let actual = await tabs.getZoom(targetTab.id); - expect(actual).to.be.lessThan(before); - expect(actual).to.equal(1); - }); -}); diff --git a/e2e/eventually.js b/e2e/eventually.js new file mode 100644 index 0000000..c04c277 --- /dev/null +++ b/e2e/eventually.js @@ -0,0 +1,25 @@ +const assert = require('assert'); + +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/karma-delay.js b/e2e/karma-delay.js deleted file mode 100644 index 7d18c4a..0000000 --- a/e2e/karma-delay.js +++ /dev/null @@ -1,10 +0,0 @@ -'use strict'; - -window.__karma__.start = (function(start){ -return function(){ - var args = arguments - setTimeout(() => { - start(args) - }, 3000); -}; -}(window.__karma__.start)); diff --git a/e2e/karma-webext-launcher.js b/e2e/karma-webext-launcher.js deleted file mode 100644 index e0a3e42..0000000 --- a/e2e/karma-webext-launcher.js +++ /dev/null @@ -1,53 +0,0 @@ -'use strict' - -var fs = require('fs') -var path = require('path') - -var PREFS = { - 'browser.shell.checkDefaultBrowser': 'false', - 'browser.bookmarks.restore_default_bookmarks': 'false', - 'dom.disable_open_during_load': 'false', - 'dom.max_script_run_time': '0', - 'dom.min_background_timeout_value': '10', - 'extensions.autoDisableScopes': '0', - 'extensions.enabledScopes': '15', -} - -var FirefoxWebExt = function (id, baseBrowserDecorator, args) { - baseBrowserDecorator(this) - - this._start = function (url) { - var self = this - var command = this._getCommand() - - let prefArgs = [].concat(...Object.keys(PREFS).map((key) => { - return ['--pref', key + '=' + PREFS[key]]; - })); - let sourceDirArgs = [].concat(...args.sourceDirs.map((dir) => { - return ['--source-dir', dir]; - })); - - self._execCommand( - command, - ['run', '--start-url', url, '--no-input'].concat(sourceDirArgs, prefArgs) - ) - } -} - -FirefoxWebExt.prototype = { - name: 'FirefoxWebExt', - - DEFAULT_CMD: { - linux: 'node_modules/web-ext/bin/web-ext', - darwin: 'node_modules/web-ext/bin/web-ext', - win32: 'node_modules/web-ext/bin/web-ext', - } -} - -FirefoxWebExt.$inject = ['id', 'baseBrowserDecorator', 'args'] - -// PUBLISH DI MODULE -module.exports = { - 'launcher:FirefoxWebExt': ['type', FirefoxWebExt], -} - diff --git a/e2e/karma.conf.js b/e2e/karma.conf.js deleted file mode 100644 index fcda415..0000000 --- a/e2e/karma.conf.js +++ /dev/null @@ -1,53 +0,0 @@ -module.exports = function (config) { - - config.set({ - basePath: '', - frameworks: ['mocha'], - files: [ - 'main.js', - 'karma-delay.js', - '**/*.test.js' - ], - - preprocessors: { - '**/main.js': ['webpack'], - '**/*.test.js': ['webpack'] - }, - - port: 9876, - colors: true, - logLevel: config.LOG_INFO, - - customLaunchers: { - FirefoxWebExtRunner: { - base: 'FirefoxWebExt', - sourceDirs: [ '.', 'e2e/ambassador'], - }, - }, - browsers: ['FirefoxWebExtRunner'], - sauceLabs: { - username: 'michael_jackson' - }, - - singleRun: true, - - webpackMiddleware: { - noInfo: true - }, - - reporters: ['mocha'], - - plugins: [ - require('./karma-webext-launcher'), - 'karma-mocha', - 'karma-webpack', - 'karma-mocha-reporter', - ], - - client: { - mocha: { - timeout: 5000 - } - } - }) -} diff --git a/e2e/main.js b/e2e/main.js deleted file mode 100644 index d923aaa..0000000 --- a/e2e/main.js +++ /dev/null @@ -1,2 +0,0 @@ -import chai from 'chai'; -global.expect = chai.expect; diff --git a/e2e/mark.test.js b/e2e/mark.test.js new file mode 100644 index 0000000..abcef03 --- /dev/null +++ b/e2e/mark.test.js @@ -0,0 +1,121 @@ +const express = require('express'); +const lanthan = require('lanthan'); +const path = require('path'); +const assert = require('power-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.installAddon(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/navigate.test.js b/e2e/navigate.test.js new file mode 100644 index 0000000..5b3a794 --- /dev/null +++ b/e2e/navigate.test.js @@ -0,0 +1,167 @@ +const express = require('express'); +const lanthan = require('lanthan'); +const path = require('path'); +const assert = require('power-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('/*', (req, res) => { + res.send(`<!DOCTYPEhtml> +<html lang="en"> + ${req.path} +</html">`); + }); + return app; +}; + +describe("zoom 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.installAddon(path.join(__dirname, '..')); + session = firefox.session; + browser = firefox.browser; + }); + + after(async() => { + if (firefox) { + await firefox.close(); + } + http.close(); + }); + + 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'); + + 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'); + + 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'); + + 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'); + + 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'); + }); + }); +}); + + diff --git a/e2e/scroll.test.js b/e2e/scroll.test.js new file mode 100644 index 0000000..7b13a72 --- /dev/null +++ b/e2e/scroll.test.js @@ -0,0 +1,150 @@ +const express = require('express'); +const lanthan = require('lanthan'); +const path = require('path'); +const assert = require('power-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.installAddon(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/tab.test.js b/e2e/tab.test.js new file mode 100644 index 0000000..93b0fc6 --- /dev/null +++ b/e2e/tab.test.js @@ -0,0 +1,202 @@ +const express = require('express'); +const lanthan = require('lanthan'); +const path = require('path'); +const assert = require('power-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.installAddon(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 by d', async () => { + 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('deletes tabs to the right by D', async () => { + await browser.tabs.update(tabs[1].id, { active: true }); + let body = await session.findElementByCSS('body'); + await body.sendKeys(Key.Shift, 'd'); + + 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/web-server/index.js b/e2e/web-server/index.js deleted file mode 100644 index 376e118..0000000 --- a/e2e/web-server/index.js +++ /dev/null @@ -1,88 +0,0 @@ -'use strict'; - -var serverUrl = require('./url'); -var http = require('http'); -var url = require('url'); - -const handleScroll = (req, res) => { - res.writeHead(200, {'Content-Type': 'text/html'}); - res.end('<!DOCTYPEhtml><html lang="en"><body style="width:10000px; height:10000px"></body></html">'); -}; - -const handleAPagenation = (req, res) => { - let u = url.parse(req.url); - let params = new url.URLSearchParams(u.search); - let page = params.get('page') === null ? null : Number(params.get('page')); - if (page === null || isNaN(page)) { - return handle404(req, res); - } - - let body = ''; - let nextLink = u.pathname + '?page=' + (page + 1); - let prevLink = u.pathname + '?page=' + (page - 1); - - if (page > 1) { - body += '<a href="' + prevLink + '">prev</a> | '; - } - body += '<a href="' + nextLink + '">next</a>'; - - res.writeHead(200, {'Content-Type': 'text/html'}); - res.end('<!DOCTYPEhtml><html lang="en"><body">' + body + '</body></html">'); -}; - -const handleLinkPagenation = (req, res) => { - let u = url.parse(req.url); - let params = new url.URLSearchParams(u.search); - let page = params.get('page') === null ? null : Number(params.get('page')); - if (page === null || isNaN(page)) { - return handle404(req, res); - } - - let head = ''; - let nextLink = u.pathname + '?page=' + (page + 1); - let prevLink = u.pathname + '?page=' + (page - 1); - - if (page > 1) { - head += '<link rel="prev" href="' + prevLink + '"></link>'; - } - head += '<link rel="next" href="' + nextLink + '"></link>'; - - res.writeHead(200, {'Content-Type': 'text/html'}); - res.end('<!DOCTYPEhtml><html lang="en"><head>' + head + '</head><body"></body></html">'); -}; - -const handleFollow = (req, res) => { - let body = ''; - body += '<a href="#a">a</a>'; - body += '<a href="#external" target="_blank">external</a>'; - body += '<img width="320" height="240" src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" usemap="#map"><map name="map"><area href="#area" shape="rect" coords="15,19,126,104"></map>' - - res.writeHead(200, {'Content-Type': 'text/html'}); - res.end('<!DOCTYPEhtml><html lang="en"><body">' + body + '</body></html">'); -} - -const handle404 = (req, res) => { - res.writeHead(404, {'Content-Type': 'text/plain'}); - res.end('not found') -}; - -http.createServer(function (req, res) { - if (req.method !== 'GET') { - handle404(req, res); - } - - let u = url.parse(req.url); - if (u.pathname === '/scroll' || u.pathname === '/mark') { - handleScroll(req, res); - } else if (u.pathname === '/a-pagenation') { - handleAPagenation(req, res); - } else if (u.pathname === '/link-pagenation') { - handleLinkPagenation(req, res); - } else if (u.pathname === '/follow') { - handleFollow(req, res); - } else { - handle404(req, res); - } - - console.log(`"${req.method} ${req.url}"`, res.statusCode) -}).listen(serverUrl.PORT, serverUrl.HOST); diff --git a/e2e/web-server/url.js b/e2e/web-server/url.js deleted file mode 100644 index 37f3d84..0000000 --- a/e2e/web-server/url.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - PORT: 11111, - HOST: '127.0.0.1', - CLIENT_URL: 'http://127.0.0.1:11111', -} diff --git a/e2e/zoom.test.js b/e2e/zoom.test.js new file mode 100644 index 0000000..1f59e3d --- /dev/null +++ b/e2e/zoom.test.js @@ -0,0 +1,81 @@ +const express = require('express'); +const lanthan = require('lanthan'); +const path = require('path'); +const assert = require('power-assert'); +const eventually = require('./eventually'); + +const Key = lanthan.Key; + +const newApp = () => { + let app = express(); + app.get('/', (req, res) => { + res.send(`<!DOCTYPEhtml> +<html lang="en"> +</html">`); + }); + return app; +}; + +describe("zoom test", () => { + + const port = 12321; + let http; + let firefox; + let session; + let browser; + let tab; + let body; + + before(async() => { + http = newApp().listen(port); + + firefox = await lanthan.firefox(); + await firefox.session.installAddon(path.join(__dirname, '..')); + session = firefox.session; + browser = firefox.browser; + tab = (await browser.tabs.query({}))[0] + }); + + 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('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); + }); + }); +}); + |