From b694afb7ce0eed4c4ee3ee9c3fae5dd35cb72d14 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Wed, 14 Feb 2018 21:11:03 +0900 Subject: [PATCH 1/5] add scroll test --- e2e/ambassador/src/background/index.js | 9 +-- e2e/ambassador/src/client/scrolls.js | 20 +++++++ e2e/ambassador/src/content/index.js | 19 +++--- e2e/ambassador/src/content/scrolls.js | 18 ++++++ e2e/ambassador/src/shared/messages.js | 4 ++ e2e/contents/scroll.test.js | 81 ++++++++++++++++++++++++++ 6 files changed, 133 insertions(+), 18 deletions(-) create mode 100644 e2e/ambassador/src/client/scrolls.js create mode 100644 e2e/ambassador/src/content/scrolls.js create mode 100644 e2e/contents/scroll.test.js diff --git a/e2e/ambassador/src/background/index.js b/e2e/ambassador/src/background/index.js index f9fda7e..c3e9dc1 100644 --- a/e2e/ambassador/src/background/index.js +++ b/e2e/ambassador/src/background/index.js @@ -2,6 +2,7 @@ import { WINDOWS_CREATE, WINDOWS_REMOVE, WINDOWS_GET, TABS_CREATE, EVENT_KEYPRESS, EVENT_KEYDOWN, EVENT_KEYUP, + SCROLL_GET, SCROLL_SET, } from '../shared/messages'; import * as tabs from './tabs'; import { receiveContentMessage } from './ipc'; @@ -19,15 +20,11 @@ receiveContentMessage((message) => { url: message.url, windowId: message.windowId, }); - } -}); - - -receiveContentMessage((message) => { - switch (message.type) { 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/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/content/index.js b/e2e/ambassador/src/content/index.js index 8573d66..93943b8 100644 --- a/e2e/ambassador/src/content/index.js +++ b/e2e/ambassador/src/content/index.js @@ -1,21 +1,12 @@ import { - WINDOWS_CREATE, WINDOWS_REMOVE, WINDOWS_GET, - TABS_CREATE, EVENT_KEYPRESS, EVENT_KEYDOWN, EVENT_KEYUP, + SCROLL_GET, SCROLL_SET, } from '../shared/messages'; import * as ipc from './ipc'; +import * as scrolls from './scrolls'; ipc.receivePageMessage((message) => { - switch (message.type) { - case WINDOWS_CREATE: - case WINDOWS_REMOVE: - case WINDOWS_GET: - case TABS_CREATE: - case EVENT_KEYPRESS: - case EVENT_KEYDOWN: - case EVENT_KEYUP: - return ipc.sendToBackground(message); - } + return ipc.sendToBackground(message); }); ipc.receiveBackgroundMesssage((message) => { @@ -32,6 +23,10 @@ ipc.receiveBackgroundMesssage((message) => { document.body.dispatchEvent( new KeyboardEvent('keyup', { 'key': message.key })); 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/scrolls.js b/e2e/ambassador/src/content/scrolls.js new file mode 100644 index 0000000..79be01d --- /dev/null +++ b/e2e/ambassador/src/content/scrolls.js @@ -0,0 +1,18 @@ +const get = () => { + let element = document.documentElement; + return { + xMax: element.scrollWidth - element.clientWidth, + yMax: element.scrollHeight - element.clientHeight, + x: element.scrollLeft, + y: element.scrollTop, + }; +}; + +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 index 32b7aa2..dd389db 100644 --- a/e2e/ambassador/src/shared/messages.js +++ b/e2e/ambassador/src/shared/messages.js @@ -7,6 +7,8 @@ const TABS_CREATE = 'tabs.create'; 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, @@ -21,4 +23,6 @@ export { EVENT_KEYPRESS, EVENT_KEYDOWN, EVENT_KEYUP, + SCROLL_GET, + SCROLL_SET, }; diff --git a/e2e/contents/scroll.test.js b/e2e/contents/scroll.test.js new file mode 100644 index 0000000..79e0d32 --- /dev/null +++ b/e2e/contents/scroll.test.js @@ -0,0 +1,81 @@ +import { expect } from "chai"; +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"; + +const SERVER_URL = "localhost:11111"; + +describe("scroll test", () => { + let targetWindow; + let targetTab; + + before(() => { + return windows.create().then((win) => { + targetWindow = win; + return tabs.create(targetWindow.id, SERVER_URL); + }).then((tab) => { + targetTab = tab; + }); + }); + + after(() => { + return windows.remove(targetWindow.id); + }); + + describe('press k', () => { + it('scrolls up', () => { + let before + return scrolls.set(targetTab.id, 100, 100).then((scroll) => { + before = scroll; + return keys.press(targetTab.id, 'k'); + }).then(() => { + return scrolls.get(targetTab.id); + }).then((actual) => { + expect(actual.y).to.be.lessThan(before.y); + }); + }); + }); + + describe('press j', () => { + it('scrolls down', () => { + let before + return scrolls.set(targetTab.id, 100, 100).then((scroll) => { + before = scroll; + return keys.press(targetTab.id, 'j'); + }).then(() => { + return scrolls.get(targetTab.id); + }).then((actual) => { + expect(actual.y).to.be.greaterThan(before.y); + }); + }); + }); + + describe('press h', () => { + it('scrolls left', () => { + let before + return scrolls.set(targetTab.id, 100, 100).then((scroll) => { + before = scroll; + return keys.press(targetTab.id, 'h'); + }).then(() => { + return scrolls.get(targetTab.id); + }).then((actual) => { + expect(actual.x).to.be.lessThan(before.x); + }); + }); + }); + + describe('press l', () => { + it('scrolls right', () => { + let before + return scrolls.set(targetTab.id, 100, 100).then((scroll) => { + before = scroll; + return keys.press(targetTab.id, 'l'); + }).then(() => { + return scrolls.get(targetTab.id); + }).then((actual) => { + expect(actual.x).to.be.greaterThan(before.x); + }); + }); + }); +}); From d4e4b7541433d527225026f51e14fc0e2c585e04 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Wed, 14 Feb 2018 21:30:04 +0900 Subject: [PATCH 2/5] add scroll tests --- e2e/ambassador/src/client/keys.js | 20 ++--- e2e/ambassador/src/content/events.js | 31 ++++++++ e2e/ambassador/src/content/index.js | 10 +-- e2e/contents/scroll.test.js | 110 ++++++++++++++++----------- 4 files changed, 112 insertions(+), 59 deletions(-) create mode 100644 e2e/ambassador/src/content/events.js diff --git a/e2e/ambassador/src/client/keys.js b/e2e/ambassador/src/client/keys.js index af0fb3d..37b9c0a 100644 --- a/e2e/ambassador/src/client/keys.js +++ b/e2e/ambassador/src/client/keys.js @@ -1,29 +1,31 @@ import { EVENT_KEYPRESS, EVENT_KEYDOWN, EVENT_KEYUP } from '../shared/messages'; import * as ipc from './ipc'; -const press = (tabId, key) => { - return ipc.send({ +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) => { - return ipc.send({ +const down = (tabId, key, modifiers = NEUTRAL_MODIFIERS) => { + return ipc.send(Object.assign({}, modifiers, { type: EVENT_KEYDOWN, tabId, key, - }); + })); }; -const up = (tabId, key) => { - return ipc.send({ +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/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 index 93943b8..fd19136 100644 --- a/e2e/ambassador/src/content/index.js +++ b/e2e/ambassador/src/content/index.js @@ -3,6 +3,7 @@ import { 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) => { @@ -12,16 +13,13 @@ ipc.receivePageMessage((message) => { ipc.receiveBackgroundMesssage((message) => { switch (message.type) { case EVENT_KEYPRESS: - document.body.dispatchEvent( - new KeyboardEvent('keypress', { 'key': message.key })); + events.keypress(message); break; case EVENT_KEYDOWN: - document.body.dispatchEvent( - new KeyboardEvent('keydown', { 'key': message.key })); + events.keydown(message); break; case EVENT_KEYUP: - document.body.dispatchEvent( - new KeyboardEvent('keyup', { 'key': message.key })); + events.keyup(message); break; case SCROLL_GET: return Promise.resolve(scrolls.get()); diff --git a/e2e/contents/scroll.test.js b/e2e/contents/scroll.test.js index 79e0d32..da14f76 100644 --- a/e2e/contents/scroll.test.js +++ b/e2e/contents/scroll.test.js @@ -23,59 +23,81 @@ describe("scroll test", () => { return windows.remove(targetWindow.id); }); - describe('press k', () => { - it('scrolls up', () => { - let before - return scrolls.set(targetTab.id, 100, 100).then((scroll) => { - before = scroll; - return keys.press(targetTab.id, 'k'); - }).then(() => { - return scrolls.get(targetTab.id); - }).then((actual) => { - expect(actual.y).to.be.lessThan(before.y); - }); + it('scrolls up by k', () => { + let before + return scrolls.set(targetTab.id, 100, 100).then((scroll) => { + before = scroll; + return keys.press(targetTab.id, 'k'); + }).then(() => { + return scrolls.get(targetTab.id); + }).then((actual) => { + expect(actual.y).to.be.lessThan(before.y); }); }); - describe('press j', () => { - it('scrolls down', () => { - let before - return scrolls.set(targetTab.id, 100, 100).then((scroll) => { - before = scroll; - return keys.press(targetTab.id, 'j'); - }).then(() => { - return scrolls.get(targetTab.id); - }).then((actual) => { - expect(actual.y).to.be.greaterThan(before.y); - }); + it('scrolls down by j', () => { + let before + return scrolls.set(targetTab.id, 100, 100).then((scroll) => { + before = scroll; + return keys.press(targetTab.id, 'j'); + }).then(() => { + return scrolls.get(targetTab.id); + }).then((actual) => { + expect(actual.y).to.be.greaterThan(before.y); }); }); - describe('press h', () => { - it('scrolls left', () => { - let before - return scrolls.set(targetTab.id, 100, 100).then((scroll) => { - before = scroll; - return keys.press(targetTab.id, 'h'); - }).then(() => { - return scrolls.get(targetTab.id); - }).then((actual) => { - expect(actual.x).to.be.lessThan(before.x); - }); + it('scrolls left by h', () => { + let before + return scrolls.set(targetTab.id, 100, 100).then((scroll) => { + before = scroll; + return keys.press(targetTab.id, 'h'); + }).then(() => { + return scrolls.get(targetTab.id); + }).then((actual) => { + expect(actual.x).to.be.lessThan(before.x); }); }); - describe('press l', () => { - it('scrolls right', () => { - let before - return scrolls.set(targetTab.id, 100, 100).then((scroll) => { - before = scroll; - return keys.press(targetTab.id, 'l'); - }).then(() => { - return scrolls.get(targetTab.id); - }).then((actual) => { - expect(actual.x).to.be.greaterThan(before.x); - }); + it('scrolls top by gg', () => { + return scrolls.set(targetTab.id, 100, 100).then((scroll) => { + return keys.press(targetTab.id, 'g'); + }).then(() => { + return keys.press(targetTab.id, 'g'); + }).then(() => { + return scrolls.get(targetTab.id); + }).then((actual) => { + expect(actual.y).to.be.equals(0); + }); + }); + + it('scrolls bottom by G', () => { + return scrolls.set(targetTab.id, 100, 100).then((scroll) => { + return keys.press(targetTab.id, 'G', { shiftKey: true }); + }).then(() => { + return scrolls.get(targetTab.id); + }).then((actual) => { + expect(actual.y).to.be.equals(actual.yMax); + }); + }); + + it('scrolls bottom by 0', () => { + return scrolls.set(targetTab.id, 100, 100).then((scroll) => { + return keys.press(targetTab.id, '0'); + }).then(() => { + return scrolls.get(targetTab.id); + }).then((actual) => { + expect(actual.x).to.be.equals(0); + }); + }); + + it('scrolls bottom by $', () => { + return scrolls.set(targetTab.id, 100, 100).then((scroll) => { + return keys.press(targetTab.id, '$'); + }).then(() => { + return scrolls.get(targetTab.id); + }).then((actual) => { + expect(actual.x).to.be.equals(actual.xMax); }); }); }); From ffd1018fa73eef644b170485cc9bd477e21804e7 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Wed, 14 Feb 2018 21:48:19 +0900 Subject: [PATCH 3/5] add scroll test --- e2e/ambassador/src/content/scrolls.js | 2 ++ e2e/contents/scroll.test.js | 48 +++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/e2e/ambassador/src/content/scrolls.js b/e2e/ambassador/src/content/scrolls.js index 79be01d..4227cf7 100644 --- a/e2e/ambassador/src/content/scrolls.js +++ b/e2e/ambassador/src/content/scrolls.js @@ -5,6 +5,8 @@ const get = () => { yMax: element.scrollHeight - element.clientHeight, x: element.scrollLeft, y: element.scrollTop, + frameWidth: element.clientWidth, + frameHeight: element.clientHeight, }; }; diff --git a/e2e/contents/scroll.test.js b/e2e/contents/scroll.test.js index da14f76..070529a 100644 --- a/e2e/contents/scroll.test.js +++ b/e2e/contents/scroll.test.js @@ -100,4 +100,52 @@ describe("scroll test", () => { expect(actual.x).to.be.equals(actual.xMax); }); }); + + it('scrolls bottom by ', () => { + let before + return scrolls.set(targetTab.id, 5000, 5000).then((scroll) => { + before = scroll; + return keys.press(targetTab.id, 'u', { ctrlKey: true }); + }).then(() => { + return scrolls.get(targetTab.id); + }).then((actual) => { + expect(actual.y).to.closeTo(before.y - before.frameHeight / 2, 1); + }); + }); + + it('scrolls bottom by ', () => { + let before + return scrolls.set(targetTab.id, 5000, 5000).then((scroll) => { + before = scroll; + return keys.press(targetTab.id, 'd', { ctrlKey: true }); + }).then(() => { + return scrolls.get(targetTab.id); + }).then((actual) => { + expect(actual.y).to.closeTo(before.y + before.frameHeight / 2, 1); + }); + }); + + it('scrolls bottom by ', () => { + let before + return scrolls.set(targetTab.id, 5000, 5000).then((scroll) => { + before = scroll; + return keys.press(targetTab.id, 'b', { ctrlKey: true }); + }).then(() => { + return scrolls.get(targetTab.id); + }).then((actual) => { + expect(actual.y).to.equals(before.y - before.frameHeight); + }); + }); + + it('scrolls bottom by ', () => { + let before + return scrolls.set(targetTab.id, 5000, 5000).then((scroll) => { + before = scroll; + return keys.press(targetTab.id, 'f', { ctrlKey: true }); + }).then(() => { + return scrolls.get(targetTab.id); + }).then((actual) => { + expect(actual.y).to.equals(before.y + before.frameHeight); + }); + }); }); From 62f73898b6754f93f730993cb5fb0debc529e839 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Wed, 14 Feb 2018 21:50:59 +0900 Subject: [PATCH 4/5] remove auto-test completed cases --- QA.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/QA.md b/QA.md index a7a0c01..37b92d7 100644 --- a/QA.md +++ b/QA.md @@ -6,12 +6,6 @@ Test operations with default key maps. #### Scrolling -- [ ] k, j: scroll up and down -- [ ] h, l: scroll left and right -- [ ] Ctrl+U, Ctrl+D: scroll up and down by half of screen -- [ ] Ctrl+B, Ctrl+F: scroll up and down by a screen -- [ ] 0, $: scroll to leftmost and rightmost -- [ ] gg, G: scroll to top and bottom - [ ] Smooth scroll by `:set smoothscroll` - [ ] Non-smooth scroll by `:set nosmoothscroll` - [ ] Configure custom hint character by settings `"smoothscroll": true`, `"smoothscroll": false` From 30d6872fa833861bc479494b2951e196f3addb60 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Thu, 15 Feb 2018 19:43:58 +0900 Subject: [PATCH 5/5] simple and stable --- e2e/contents/tab.test.js | 50 ++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/e2e/contents/tab.test.js b/e2e/contents/tab.test.js index 198bf0a..707acef 100644 --- a/e2e/contents/tab.test.js +++ b/e2e/contents/tab.test.js @@ -18,31 +18,37 @@ describe("tab test", () => { return windows.remove(targetWindow.id); }); - describe('press d', () => { - it('deletes tab', () => { - return tabs.create(targetWindow.id, SERVER_URL).then((tab) => { - return keys.press(tab.id, 'd'); - }).then(() => { - return windows.get(targetWindow.id); - }).then((after) => { - expect(after.tabs).to.have.lengthOf(1); - }); + it('deletes tab by d', () => { + let before; + let targetTab; + return tabs.create(targetWindow.id, SERVER_URL).then((tab) => { + targetTab = tab; + return windows.get(targetWindow.id); + }).then((win) => { + before = win; + return keys.press(targetTab.id, 'd'); + }).then(() => { + return windows.get(targetWindow.id); + }).then((actual) => { + expect(actual.tabs).to.have.lengthOf(before.tabs.length - 1); }); }); - describe('press zd', () => { - it('duplicates tab', () => { - let targetTab = 0; - return tabs.create(targetWindow.id, SERVER_URL).then((tab) => { - targetTab = tab; - return keys.press(targetTab.id, 'z'); - }).then(() => { - return keys.press(targetTab.id, 'd'); - }).then(() => { - return windows.get(targetWindow.id); - }).then((after) => { - expect(after.tabs).to.have.lengthOf(3); - }); + it('duplicates tab by zd', () => { + let before; + let targetTab; + return tabs.create(targetWindow.id, SERVER_URL).then((tab) => { + targetTab = tab; + return windows.get(targetWindow.id) + }).then((win) => {; + before = win; + return keys.press(targetTab.id, 'z'); + }).then(() => { + return keys.press(targetTab.id, 'd'); + }).then(() => { + return windows.get(targetWindow.id); + }).then((actual) => { + expect(actual.tabs).to.have.lengthOf(before.tabs.length + 1); }); }) });