Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ulixee
GitHub Repository: ulixee/secret-agent
Path: blob/main/full-client/test/tab.test.ts
1028 views
1
import { Helpers } from '@secret-agent/testing';
2
import { Command } from '@secret-agent/client/interfaces/IInteractions';
3
import { KeyboardKeys } from '@secret-agent/interfaces/IKeyboardLayoutUS';
4
import * as os from 'os';
5
import { ITestKoaServer } from '@secret-agent/testing/helpers';
6
import { Handler } from '../index';
7
8
let koaServer: ITestKoaServer;
9
let handler: Handler;
10
beforeAll(async () => {
11
handler = new Handler();
12
Helpers.onClose(() => handler.close(), true);
13
koaServer = await Helpers.runKoaServer();
14
koaServer.get('/tabTest', ctx => {
15
ctx.body = `<body>
16
<a target="_blank" href="/newTab">Nothing really here</a>
17
</body>`;
18
});
19
koaServer.get('/newTab', ctx => {
20
ctx.body = `<body>
21
<h1 id="newTabHeader">You are here</h1>
22
<a href="#hash">Go back</a>
23
</body>`;
24
});
25
});
26
afterAll(Helpers.afterAll);
27
afterEach(Helpers.afterEach);
28
29
describe('Multi-tab scenarios', () => {
30
it('can wait for another tab', async () => {
31
const agent = await handler.createAgent();
32
Helpers.needsClosing.push(agent);
33
34
await agent.goto(`${koaServer.baseUrl}/tabTest`);
35
const tab1 = agent.activeTab;
36
const url = await agent.document.location.host;
37
expect(url).toBe(koaServer.baseHost);
38
39
await agent.click(agent.document.querySelector('a'));
40
const newTab = await agent.waitForNewTab();
41
42
expect(await agent.tabs).toHaveLength(2);
43
expect(newTab.tabId).not.toBe(agent.activeTab.tabId);
44
expect(await newTab.url).toBe(`${koaServer.baseUrl}/newTab`);
45
await agent.focusTab(newTab);
46
expect(await agent.activeTab.url).toBe(`${koaServer.baseUrl}/newTab`);
47
const { document } = agent;
48
expect(await document.querySelector('#newTabHeader').textContent).toBe('You are here');
49
50
await agent.click(agent.document.querySelector('a'));
51
expect(await agent.activeTab.url).toBe(`${koaServer.baseUrl}/newTab#hash`);
52
53
const meta = await agent.meta;
54
// make sure user agent is wired up
55
const navigatorAgent = await agent.getJsValue('navigator.userAgent');
56
expect(navigatorAgent).toBe(meta.userAgentString);
57
58
// make sure polyfills ran
59
const csi = await agent.getJsValue<any>('chrome.csi()');
60
expect(csi.startE).toBeTruthy();
61
62
await agent.closeTab(newTab);
63
const newTabList = await agent.tabs;
64
expect(newTabList).toHaveLength(1);
65
expect(agent.activeTab).toBe(tab1);
66
});
67
68
it('can wait for resources in each tab', async () => {
69
koaServer.get('/logo.png', ctx => {
70
ctx.set('Content-Type', 'image/png');
71
ctx.body = Helpers.getLogo();
72
});
73
koaServer.get('/page1', ctx => {
74
ctx.body = `<body>
75
<img src="/logo.png?page=page1" alt="logo"/>
76
<img src="/logo.png" alt="logo"/>
77
<a target="_blank" href="/page2">Nothing really here</a>
78
</body>`;
79
});
80
koaServer.get('/page2', ctx => {
81
ctx.body = `<body>
82
<h1 id="newTabHeader">You are here</h1>
83
<img src="/logo.png?page=page2" alt="logo"/>
84
<img src="/logo.png" alt="logo"/>
85
<a href="/page1" id="back">Go back</a>
86
<a href="/page3" id="fwd">Go back</a>
87
</body>`;
88
});
89
koaServer.get('/page3', ctx => {
90
ctx.body = `<body><h1>Final</h1></body>`;
91
});
92
93
const agent = await handler.createAgent();
94
Helpers.needsClosing.push(agent);
95
96
await agent.goto(`${koaServer.baseUrl}/page1`);
97
await agent.waitForPaintingStable();
98
expect(await agent.tabs).toHaveLength(1);
99
expect(await agent.url).toBe(`${koaServer.baseUrl}/page1`);
100
101
const startCommandId = await agent.lastCommandId;
102
await agent.click(agent.document.querySelector('a'));
103
104
const tab1 = agent.activeTab;
105
const page1Logos = await tab1.waitForResource({
106
url: '/logo.png',
107
});
108
expect(page1Logos).toHaveLength(2);
109
const urls = await Promise.all([page1Logos[0].request.url, page1Logos[1].request.url]);
110
urls.sort();
111
expect(urls).toStrictEqual([
112
`${koaServer.baseUrl}/logo.png`,
113
`${koaServer.baseUrl}/logo.png?page=page1`,
114
]);
115
await agent.waitForNewTab({ sinceCommandId: startCommandId });
116
117
const tabs = await agent.tabs;
118
expect(tabs).toHaveLength(2);
119
const tab2 = tabs[1];
120
const page2Logos = await tab2.waitForResource({
121
url: '/logo.png?page=page2',
122
});
123
expect(page2Logos).toHaveLength(1);
124
expect(await page2Logos[0].request.url).toBe(`${koaServer.baseUrl}/logo.png?page=page2`);
125
await tab2.focus();
126
await tab2.waitForPaintingStable();
127
await agent.click(tab2.document.querySelector('#fwd'));
128
await tab2.waitForLocation('change');
129
expect(await agent.url).toBe(`${koaServer.baseUrl}/page3`);
130
expect(await tab2.url).toBe(`${koaServer.baseUrl}/page3`);
131
expect(await tab1.url).toBe(`${koaServer.baseUrl}/page1`);
132
}, 30e3);
133
134
it('can command click on a link to get to a new tab', async () => {
135
koaServer.get('/tabTest2', ctx => {
136
ctx.body = `<body>
137
<a href="/newTab">Nothing else really here</a>
138
</body>`;
139
});
140
141
const agent = await handler.createAgent();
142
Helpers.needsClosing.push(agent);
143
144
await agent.goto(`${koaServer.baseUrl}/tabTest2`);
145
const newTabKey = os.platform() === 'darwin' ? KeyboardKeys.MetaLeft : KeyboardKeys.ControlLeft;
146
await agent.interact({
147
[Command.keyDown]: newTabKey,
148
});
149
await agent.click(agent.document.querySelector('a'));
150
const newTab = await agent.waitForNewTab();
151
152
expect(await newTab.tabId).not.toBe(await agent.activeTab.tabId);
153
expect(await newTab.url).toBe(`${koaServer.baseUrl}/newTab`);
154
await agent.focusTab(newTab);
155
const { document } = newTab;
156
expect(await document.querySelector('#newTabHeader').textContent).toBe('You are here');
157
158
await agent.click(document.querySelector('a'));
159
expect(await agent.activeTab.url).toBe(`${koaServer.baseUrl}/newTab#hash`);
160
161
const meta = await agent.meta;
162
// make sure user agent is wired up
163
const navigatorAgent = await agent.getJsValue('navigator.userAgent');
164
expect(navigatorAgent).toBe(meta.userAgentString);
165
166
// make sure polyfills ran
167
const csi = await agent.getJsValue<any>('chrome.csi()');
168
expect(csi.startE).toBeTruthy();
169
170
await agent.closeTab(newTab);
171
});
172
173
it('can handle new tabs created in js callbacks', async () => {
174
koaServer.get('/ajaxNewResult', ctx => {
175
ctx.body = '<h1>Overridden Result</h1>';
176
});
177
koaServer.get('/ajaxTab', ctx => {
178
ctx.body = `<body>
179
<a href="/newTab">Nothing else really here</a>
180
<script>
181
document.querySelector('a').addEventListener('click', event => {
182
// Prevent default link behavior
183
event.preventDefault();
184
event.stopPropagation();
185
186
// Simulate Asynchronous delay
187
setTimeout(function(){
188
window.open('${koaServer.baseUrl}/ajaxNewResult', '_blank');
189
}, 100);
190
return false;
191
})
192
</script>
193
</body>`;
194
});
195
196
const agent = await handler.createAgent();
197
Helpers.needsClosing.push(agent);
198
199
await agent.goto(`${koaServer.baseUrl}/ajaxTab`);
200
await agent.click(agent.document.querySelector('a'));
201
const newTab = await agent.waitForNewTab();
202
203
expect(await newTab.tabId).not.toBe(await agent.activeTab.tabId);
204
expect(await newTab.url).toBe(`${koaServer.baseUrl}/ajaxNewResult`);
205
await agent.focusTab(newTab);
206
const { document } = newTab;
207
expect(await document.querySelector('h1').textContent).toBe('Overridden Result');
208
209
const meta = await agent.meta;
210
// make sure user agent is wired up
211
const navigatorAgent = await agent.getJsValue('navigator.userAgent');
212
expect(navigatorAgent).toBe(meta.userAgentString);
213
214
await agent.closeTab(newTab);
215
});
216
});
217
218