diff options
Diffstat (limited to 'e2e')
33 files changed, 744 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..ab0ae25 --- /dev/null +++ b/e2e/eventually.js @@ -0,0 +1,23 @@ +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..8f350b7 --- /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('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..089fa56 --- /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('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..32b0012 --- /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('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..39338aa --- /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('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..bc89628 --- /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('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); +    }); +  }); +}); +  | 
