commit
e9a6fb8558
13 changed files with 479 additions and 64 deletions
@ -0,0 +1,121 @@ |
||||
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(() => { |
||||
return windows.create(CLIENT_URL).then((win) => { |
||||
targetWindow = win; |
||||
}); |
||||
}); |
||||
|
||||
afterEach(() => { |
||||
return windows.remove(targetWindow.id); |
||||
}); |
||||
|
||||
it('follows link by `f`', () => { |
||||
let targetTab; |
||||
return tabs.create(targetWindow.id, CLIENT_URL + '/follow').then((tab) => { |
||||
targetTab = tab; |
||||
return keys.press(targetTab.id, 'f'); |
||||
}).then(() => { |
||||
return new Promise(resolve => { setTimeout(() => resolve(), 10) }); |
||||
}).then(() => { |
||||
return keys.press(targetTab.id, 'a'); |
||||
}).then(() => { |
||||
return new Promise(resolve => { setTimeout(() => resolve(), 10) }); |
||||
}).then(() => { |
||||
return tabs.get(targetTab.id); |
||||
}).then((tab) => { |
||||
expect(tab.url).to.be.equal(CLIENT_URL + '/follow#a'); |
||||
}); |
||||
}); |
||||
|
||||
it('follows link into new tab by `F`', () => { |
||||
let targetTab; |
||||
return tabs.create(targetWindow.id, CLIENT_URL + '/follow').then((tab) => { |
||||
targetTab = tab; |
||||
return keys.press(targetTab.id, 'F', { shiftKey: true }); |
||||
}).then(() => { |
||||
return new Promise(resolve => { setTimeout(() => resolve(), 10) }); |
||||
}).then(() => { |
||||
return keys.press(targetTab.id, 'a'); |
||||
}).then(() => { |
||||
return new Promise(resolve => { setTimeout(() => resolve(), 500) }); |
||||
}).then(() => { |
||||
return windows.get(targetWindow.id); |
||||
}).then((win) => { |
||||
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`', () => { |
||||
let targetTab; |
||||
return tabs.create(targetWindow.id, CLIENT_URL + '/follow').then((tab) => { |
||||
targetTab = tab; |
||||
return keys.press(targetTab.id, 'f'); |
||||
}).then(() => { |
||||
return new Promise(resolve => { setTimeout(() => resolve(), 10) }); |
||||
}).then(() => { |
||||
return keys.press(targetTab.id, 'b'); |
||||
}).then(() => { |
||||
return new Promise(resolve => { setTimeout(() => resolve(), 500) }); |
||||
}).then(() => { |
||||
return windows.get(targetWindow.id); |
||||
}).then((win) => { |
||||
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`', () => { |
||||
let targetTab; |
||||
return tabs.create(targetWindow.id, CLIENT_URL + '/follow').then((tab) => { |
||||
targetTab = tab; |
||||
return keys.press(targetTab.id, 'F', { shiftKey: true }); |
||||
}).then(() => { |
||||
}).then(() => { |
||||
return new Promise(resolve => { setTimeout(() => resolve(), 10) }); |
||||
}).then(() => { |
||||
return keys.press(targetTab.id, 'b'); |
||||
}).then(() => { |
||||
return new Promise(resolve => { setTimeout(() => resolve(), 500) }); |
||||
}).then(() => { |
||||
return windows.get(targetWindow.id); |
||||
}).then((win) => { |
||||
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`', () => { |
||||
let targetTab; |
||||
return tabs.create(targetWindow.id, CLIENT_URL + '/follow').then((tab) => { |
||||
targetTab = tab; |
||||
return keys.press(targetTab.id, 'f'); |
||||
}).then(() => { |
||||
return new Promise(resolve => { setTimeout(() => resolve(), 10) }); |
||||
}).then(() => { |
||||
return keys.press(targetTab.id, 'c'); |
||||
}).then(() => { |
||||
return new Promise(resolve => { setTimeout(() => resolve(), 10) }); |
||||
}).then(() => { |
||||
return tabs.get(targetTab.id); |
||||
}).then((tab) => { |
||||
expect(tab.url).to.be.equal(CLIENT_URL + '/follow#area'); |
||||
}); |
||||
}); |
||||
}); |
@ -0,0 +1,156 @@ |
||||
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(() => { |
||||
return windows.create().then((win) => { |
||||
targetWindow = win; |
||||
return tabs.create(targetWindow.id, CLIENT_URL); |
||||
}); |
||||
}); |
||||
|
||||
after(() => { |
||||
return windows.remove(targetWindow.id); |
||||
}); |
||||
|
||||
it('goes to parent', () => { |
||||
let targetTab; |
||||
return tabs.create(targetWindow.id, CLIENT_URL + '/a/b/c').then((tab) => { |
||||
targetTab = tab; |
||||
return keys.press(targetTab.id, 'g'); |
||||
}).then(() => { |
||||
return keys.press(targetTab.id, 'u'); |
||||
}).then(() => { |
||||
return new Promise(resolve => { setTimeout(() => resolve(), 10) }); |
||||
}).then(() => { |
||||
return tabs.get(targetTab.id); |
||||
}).then((tab) => { |
||||
expect(tab.url).to.be.equal(CLIENT_URL + '/a/b/'); |
||||
}); |
||||
}); |
||||
|
||||
it('removes hash', () => { |
||||
let targetTab; |
||||
return tabs.create(targetWindow.id, CLIENT_URL + '/a/b/c#navigate').then((tab) => { |
||||
targetTab = tab; |
||||
return keys.press(targetTab.id, 'g'); |
||||
}).then(() => { |
||||
return keys.press(targetTab.id, 'u'); |
||||
}).then(() => { |
||||
return tabs.get(targetTab.id); |
||||
}).then((tab) => { |
||||
expect(tab.url).to.be.equal(CLIENT_URL + '/a/b/c#'); |
||||
}); |
||||
}); |
||||
|
||||
it('goes to root', () => { |
||||
let targetTab; |
||||
return tabs.create(targetWindow.id, CLIENT_URL + '/a/b/c').then((tab) => { |
||||
targetTab = tab; |
||||
return keys.press(targetTab.id, 'g'); |
||||
}).then(() => { |
||||
return keys.press(targetTab.id, 'U', { shiftKey: true }); |
||||
}).then(() => { |
||||
return new Promise(resolve => { setTimeout(() => resolve(), 10) }); |
||||
}).then(() => { |
||||
return tabs.get(targetTab.id); |
||||
}).then((tab) => { |
||||
expect(tab.url).to.be.equal(CLIENT_URL + '/'); |
||||
}); |
||||
}); |
||||
|
||||
it('goes back and forward in history', () => { |
||||
let targetTab; |
||||
return tabs.create(targetWindow.id, CLIENT_URL + '/#navigate').then((tab) => { |
||||
targetTab = tab; |
||||
return keys.press(targetTab.id, 'g'); |
||||
}).then(() => { |
||||
return keys.press(targetTab.id, 'u'); |
||||
}).then(() => { |
||||
return keys.press(targetTab.id, 'H', { shiftKey: true }); |
||||
}).then(() => { |
||||
return new Promise(resolve => { setTimeout(() => resolve(), 10) }); |
||||
}).then(() => { |
||||
return tabs.get(targetTab.id); |
||||
}).then((tab) => { |
||||
expect(tab.url, 'go back in history').to.be.equal(CLIENT_URL + '/#navigate'); |
||||
}).then(() => { |
||||
return new Promise(resolve => { setTimeout(() => resolve(), 10) }); |
||||
}).then(() => { |
||||
return keys.press(targetTab.id, 'L', { shiftKey: true }); |
||||
}).then(() => { |
||||
return tabs.get(targetTab.id); |
||||
}).then((tab) => { |
||||
expect(tab.url, 'go next in history').to.be.equal(CLIENT_URL + '/#'); |
||||
}); |
||||
}); |
||||
|
||||
it('goes previous page by <a>', () => { |
||||
let targetTab; |
||||
return tabs.create(targetWindow.id, CLIENT_URL + '/a-pagenation?page=10').then((tab) => { |
||||
targetTab = tab; |
||||
return keys.press(targetTab.id, '['); |
||||
}).then(() => { |
||||
return keys.press(targetTab.id, '['); |
||||
}).then(() => { |
||||
return new Promise(resolve => { setTimeout(() => resolve(), 10) }); |
||||
}).then(() => { |
||||
return tabs.get(targetTab.id); |
||||
}).then((tab) => { |
||||
expect(tab.url).to.be.equal(CLIENT_URL + '/a-pagenation?page=9'); |
||||
}); |
||||
}) |
||||
|
||||
it('goes next page by <a>', () => { |
||||
let targetTab; |
||||
return tabs.create(targetWindow.id, CLIENT_URL + '/a-pagenation?page=10').then((tab) => { |
||||
targetTab = tab; |
||||
return keys.press(targetTab.id, ']'); |
||||
}).then(() => { |
||||
return keys.press(targetTab.id, ']'); |
||||
}).then(() => { |
||||
return new Promise(resolve => { setTimeout(() => resolve(), 10) }); |
||||
}).then(() => { |
||||
return tabs.get(targetTab.id); |
||||
}).then((tab) => { |
||||
expect(tab.url).to.be.equal(CLIENT_URL + '/a-pagenation?page=11'); |
||||
}); |
||||
}) |
||||
|
||||
it('goes previous page by <link>', () => { |
||||
let targetTab; |
||||
return tabs.create(targetWindow.id, CLIENT_URL + '/link-pagenation?page=10').then((tab) => { |
||||
targetTab = tab; |
||||
return keys.press(targetTab.id, '['); |
||||
}).then(() => { |
||||
return keys.press(targetTab.id, '['); |
||||
}).then(() => { |
||||
return new Promise(resolve => { setTimeout(() => resolve(), 10) }); |
||||
}).then(() => { |
||||
return tabs.get(targetTab.id); |
||||
}).then((tab) => { |
||||
expect(tab.url).to.be.equal(CLIENT_URL + '/link-pagenation?page=9'); |
||||
}); |
||||
}) |
||||
|
||||
it('goes next page by <link>', () => { |
||||
let targetTab; |
||||
return tabs.create(targetWindow.id, CLIENT_URL + '/link-pagenation?page=10').then((tab) => { |
||||
targetTab = tab; |
||||
return keys.press(targetTab.id, ']'); |
||||
}).then(() => { |
||||
return keys.press(targetTab.id, ']'); |
||||
}).then(() => { |
||||
return new Promise(resolve => { setTimeout(() => resolve(), 10) }); |
||||
}).then(() => { |
||||
return tabs.get(targetTab.id); |
||||
}).then((tab) => { |
||||
expect(tab.url).to.be.equal(CLIENT_URL + '/link-pagenation?page=11'); |
||||
}); |
||||
}) |
||||
}); |
@ -1,14 +1,88 @@ |
||||
'use strict'; |
||||
|
||||
var serverUrl = require('./url'); |
||||
var http = require('http'); |
||||
var url = require('url'); |
||||
|
||||
const content = |
||||
'<!DOCTYPE html>' + |
||||
'<html lang="en">' + |
||||
'<body style="width:10000px; height:10000px">' + |
||||
'</body>' + |
||||
'</html">' ; |
||||
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>'; |
||||
|
||||
http.createServer(function (req, res) { |
||||
res.writeHead(200, {'Content-Type': 'text/html'}); |
||||
res.end(content); |
||||
}).listen(11111, '127.0.0.1'); |
||||
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') { |
||||
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); |
||||
|
@ -0,0 +1,5 @@ |
||||
module.exports = { |
||||
PORT: 11111, |
||||
HOST: '127.0.0.1', |
||||
CLIENT_URL: 'http://127.0.0.1:11111', |
||||
} |
Reference in new issue