diff options
author | Shin'ya Ueoka <ueokande@i-beam.org> | 2018-05-01 15:51:40 +0900 |
---|---|---|
committer | Shin'ya Ueoka <ueokande@i-beam.org> | 2018-05-01 15:51:40 +0900 |
commit | 9da2f5fd786ff7ef64eca0a86efb1c0b9a164244 (patch) | |
tree | b888349817d0016dc1499932671bbe6cd95efdaa /e2e/ambassador | |
parent | f9889b7f2b634bfe5a540633d8952f4a6f900658 (diff) | |
parent | 89d6afecfd257ff4fc62748f771abf37ef3a2852 (diff) |
Merge remote-tracking branch 'origin/master' into patch-1
Diffstat (limited to 'e2e/ambassador')
-rw-r--r-- | e2e/ambassador/manifest.json | 28 | ||||
-rw-r--r-- | e2e/ambassador/src/background/index.js | 42 | ||||
-rw-r--r-- | e2e/ambassador/src/background/ipc.js | 7 | ||||
-rw-r--r-- | e2e/ambassador/src/background/tabs.js | 26 | ||||
-rw-r--r-- | e2e/ambassador/src/client/ipc.js | 29 | ||||
-rw-r--r-- | e2e/ambassador/src/client/keys.js | 31 | ||||
-rw-r--r-- | e2e/ambassador/src/client/scrolls.js | 20 | ||||
-rw-r--r-- | e2e/ambassador/src/client/tabs.js | 37 | ||||
-rw-r--r-- | e2e/ambassador/src/client/windows.js | 27 | ||||
-rw-r--r-- | e2e/ambassador/src/content/events.js | 31 | ||||
-rw-r--r-- | e2e/ambassador/src/content/index.js | 30 | ||||
-rw-r--r-- | e2e/ambassador/src/content/ipc.js | 40 | ||||
-rw-r--r-- | e2e/ambassador/src/content/scrolls.js | 20 | ||||
-rw-r--r-- | e2e/ambassador/src/shared/messages.js | 34 | ||||
-rw-r--r-- | e2e/ambassador/webpack.config.js | 24 |
15 files changed, 426 insertions, 0 deletions
diff --git a/e2e/ambassador/manifest.json b/e2e/ambassador/manifest.json new file mode 100644 index 0000000..d2253f6 --- /dev/null +++ b/e2e/ambassador/manifest.json @@ -0,0 +1,28 @@ +{ + "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 new file mode 100644 index 0000000..db2deb3 --- /dev/null +++ b/e2e/ambassador/src/background/index.js @@ -0,0 +1,42 @@ +import { + WINDOWS_CREATE, WINDOWS_REMOVE, WINDOWS_GET, + TABS_CREATE, TABS_SELECT_AT, 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_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 new file mode 100644 index 0000000..95d2164 --- /dev/null +++ b/e2e/ambassador/src/background/ipc.js @@ -0,0 +1,7 @@ +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 new file mode 100644 index 0000000..d049500 --- /dev/null +++ b/e2e/ambassador/src/background/tabs.js @@ -0,0 +1,26 @@ +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); + resolve(tab); + } + }; + 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 new file mode 100644 index 0000000..9f232ea --- /dev/null +++ b/e2e/ambassador/src/client/ipc.js @@ -0,0 +1,29 @@ +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 new file mode 100644 index 0000000..37b9c0a --- /dev/null +++ b/e2e/ambassador/src/client/keys.js @@ -0,0 +1,31 @@ +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(Object.assign({}, modifiers, { + type: EVENT_KEYPRESS, + tabId, + key, + })); +}; + +const down = (tabId, key, modifiers = NEUTRAL_MODIFIERS) => { + return ipc.send(Object.assign({}, modifiers, { + type: EVENT_KEYDOWN, + tabId, + key, + })); +}; + + +const up = (tabId, key, modifiers = NEUTRAL_MODIFIERS) => { + return ipc.send(Object.assign({}, 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 new file mode 100644 index 0000000..f8f82e9 --- /dev/null +++ b/e2e/ambassador/src/client/scrolls.js @@ -0,0 +1,20 @@ +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 new file mode 100644 index 0000000..c7b1340 --- /dev/null +++ b/e2e/ambassador/src/client/tabs.js @@ -0,0 +1,37 @@ +import { + TABS_CREATE, TABS_SELECT_AT, 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 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, getZoom, setZoom }; diff --git a/e2e/ambassador/src/client/windows.js b/e2e/ambassador/src/client/windows.js new file mode 100644 index 0000000..f92405a --- /dev/null +++ b/e2e/ambassador/src/client/windows.js @@ -0,0 +1,27 @@ +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 new file mode 100644 index 0000000..1e45909 --- /dev/null +++ b/e2e/ambassador/src/content/events.js @@ -0,0 +1,31 @@ +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 new file mode 100644 index 0000000..fd19136 --- /dev/null +++ b/e2e/ambassador/src/content/index.js @@ -0,0 +1,30 @@ +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 new file mode 100644 index 0000000..917623c --- /dev/null +++ b/e2e/ambassador/src/content/ipc.js @@ -0,0 +1,40 @@ +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 new file mode 100644 index 0000000..4227cf7 --- /dev/null +++ b/e2e/ambassador/src/content/scrolls.js @@ -0,0 +1,20 @@ +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 new file mode 100644 index 0000000..1fc47d2 --- /dev/null +++ b/e2e/ambassador/src/shared/messages.js @@ -0,0 +1,34 @@ +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_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_CREATE, + TABS_SELECT_AT, + TABS_GET_ZOOM, + TABS_SET_ZOOM, + + EVENT_KEYPRESS, + EVENT_KEYDOWN, + EVENT_KEYUP, + SCROLL_GET, + SCROLL_SET, +}; diff --git a/e2e/ambassador/webpack.config.js b/e2e/ambassador/webpack.config.js new file mode 100644 index 0000000..d292317 --- /dev/null +++ b/e2e/ambassador/webpack.config.js @@ -0,0 +1,24 @@ +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 + |