Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ulixee
GitHub Repository: ulixee/secret-agent
Path: blob/main/full-client/test/waitForLocation.test.ts
1028 views
1
import { Helpers } from '@secret-agent/testing';
2
import Resolvable from '@secret-agent/commons/Resolvable';
3
import { getLogo, ITestKoaServer } from '@secret-agent/testing/helpers';
4
import { Handler } from '../index';
5
6
let handler: Handler;
7
let koaServer: ITestKoaServer;
8
beforeAll(async () => {
9
handler = new Handler();
10
koaServer = await Helpers.runKoaServer(true);
11
Helpers.onClose(() => handler.close(), true);
12
});
13
afterAll(Helpers.afterAll);
14
afterEach(Helpers.afterEach);
15
16
describe('basic waitForLocation change detections', () => {
17
it('runs basic flow', async () => {
18
koaServer.get('/start', ctx => {
19
ctx.body = `
20
<body>
21
<button>Click Me</button>
22
<script>
23
document.querySelector('button').addEventListener('click', () => {
24
window.location = '/finish';
25
});
26
</script>
27
</body>
28
`;
29
});
30
koaServer.get('/finish', ctx => (ctx.body = `Finished!`));
31
32
const startUrl = `${koaServer.baseUrl}/start`;
33
const finishUrl = `${koaServer.baseUrl}/finish`;
34
const agent = await handler.createAgent();
35
36
await agent.goto(startUrl);
37
const firstUrl = await agent.url;
38
await agent.waitForPaintingStable();
39
const button = agent.document.querySelector('button');
40
await agent.waitForElement(button);
41
42
await agent.interact({ click: button });
43
await agent.waitForLocation('change');
44
const lastUrl = await agent.url;
45
46
expect(firstUrl).toBe(startUrl);
47
expect(lastUrl).toBe(finishUrl);
48
49
await agent.close();
50
});
51
52
it('should trigger a location change if location changed but also redirected', async () => {
53
koaServer.get('/page1', ctx => {
54
ctx.body = `
55
<body>
56
<a href="/page2">Click Me</a>
57
</body>
58
`;
59
});
60
koaServer.get('/page2', ctx => {
61
ctx.redirect('/page3');
62
});
63
64
koaServer.get('/page3', ctx => {
65
ctx.body = `
66
<body>
67
<a href="/page4">Click Me</a>
68
</body>
69
`;
70
});
71
72
koaServer.get('/page4', ctx => {
73
ctx.redirect('/finish');
74
});
75
76
koaServer.get('/finish', ctx => (ctx.body = `Finished!`));
77
const agent = await handler.createAgent();
78
await agent.goto(`${koaServer.baseUrl}/page1`);
79
const startlink = agent.document.querySelector('a');
80
await agent.interact({ click: startlink, waitForElementVisible: startlink });
81
await agent.waitForLocation('change');
82
expect(await agent.url).toBe(`${koaServer.baseUrl}/page3`);
83
84
const nextlink = agent.document.querySelector('a');
85
await agent.interact({ click: nextlink, waitForElementVisible: nextlink });
86
await agent.waitForLocation('change');
87
expect(await agent.url).toBe(`${koaServer.baseUrl}/finish`);
88
89
await agent.close();
90
});
91
92
it('should support 2 location changes', async () => {
93
koaServer.get('/loc1', ctx => {
94
ctx.body = `
95
<body>
96
<a href="/loc2">Click Me</a>
97
</body>
98
`;
99
});
100
koaServer.get('/loc2', ctx => {
101
ctx.body = `
102
<body>
103
<a href="/loc3">Click Me</a>
104
</body>
105
`;
106
});
107
koaServer.get('/loc3', ctx => (ctx.body = `Finished!`));
108
109
const startUrl = `${koaServer.baseUrl}/loc1`;
110
const page2Url = `${koaServer.baseUrl}/loc2`;
111
const finishUrl = `${koaServer.baseUrl}/loc3`;
112
const agent = await handler.createAgent();
113
114
await agent.goto(startUrl);
115
const firstUrl = await agent.url;
116
await agent.waitForPaintingStable();
117
const readyLink = agent.document.querySelector('a');
118
await agent.interact({ click: readyLink, waitForElementVisible: readyLink });
119
await agent.waitForLocation('change');
120
const secondUrl = await agent.url;
121
await agent.waitForPaintingStable();
122
123
const readyLink2 = agent.document.querySelector('a');
124
await agent.interact({ click: readyLink2, waitForElementVisible: readyLink2 });
125
await agent.waitForLocation('change');
126
await agent.waitForPaintingStable();
127
const lastUrl = await agent.url;
128
129
expect(firstUrl).toBe(startUrl);
130
expect(secondUrl).toBe(page2Url);
131
expect(lastUrl).toBe(finishUrl);
132
133
await agent.close();
134
});
135
136
it('should trigger location change when a page redirects in-page before load', async () => {
137
const imagePromise = new Resolvable();
138
koaServer.get('/img.png', async ctx => {
139
ctx.set('Content-Type', 'image/png');
140
await imagePromise.promise;
141
ctx.body = getLogo();
142
});
143
144
koaServer.get('/change-form', ctx => {
145
ctx.body = `
146
<body>
147
<form action="/change-inpage" method="get">
148
<input type="submit" name="submit" value="value" >
149
</form>
150
</body>
151
`;
152
});
153
154
koaServer.get('/change-inpage', ctx => {
155
ctx.body = `
156
<body>
157
<script>
158
history.pushState({}, '', '/change-inpage/1');
159
</script>
160
<img src="/img.png">
161
</body>
162
`;
163
});
164
165
const agent = await handler.createAgent();
166
167
await agent.goto(`${koaServer.baseUrl}/change-form`);
168
await agent.interact({ click: agent.document.querySelector('input') });
169
const result = await agent.waitForLocation('change');
170
await expect(result.response.url).resolves.toBe(
171
`${koaServer.baseUrl}/change-inpage?submit=value`,
172
);
173
imagePromise.resolve(null);
174
await agent.waitForPaintingStable();
175
await expect(agent.url).resolves.toBe(`${koaServer.baseUrl}/change-inpage/1`);
176
177
await agent.close();
178
});
179
180
it('should support timing out a location change', async () => {
181
koaServer.get('/loaded1', ctx => {
182
ctx.body = `
183
<body>
184
<a href="/loaded2">Click Me</a>
185
</body>
186
`;
187
});
188
koaServer.get('/loaded2', ctx => {
189
ctx.body = `<body><h1>Loaded 2</h1></body>`;
190
});
191
192
const agent = await handler.createAgent();
193
194
await agent.goto(`${koaServer.baseUrl}/loaded1`);
195
await agent.waitForPaintingStable();
196
const link = agent.document.querySelector('a');
197
await agent.click(link);
198
await agent.waitForLocation('change', { timeoutMs: 500 });
199
await agent.waitForPaintingStable();
200
expect(await agent.url).toBe(`${koaServer.baseUrl}/loaded2`);
201
202
await expect(agent.waitForLocation('change', { timeoutMs: 500 })).rejects.toThrowError(
203
'Timeout',
204
);
205
await agent.close();
206
});
207
208
it('can wait for a reload', async () => {
209
let counter = 0;
210
koaServer.get('/refresh', ctx => {
211
if (counter === 0) {
212
ctx.body = `
213
<head><meta http-equiv = "refresh" content = "0; url = ${koaServer.baseUrl}/refresh" /></head>
214
<body><h1>Hi</h1></body>
215
`;
216
} else {
217
ctx.body = `
218
<body><h1>Loaded</h1></body>
219
`;
220
}
221
counter += 1;
222
});
223
const agent = await handler.createAgent();
224
await agent.goto(`${koaServer.baseUrl}/refresh`);
225
226
await expect(agent.waitForLocation('reload')).resolves.toBeTruthy();
227
});
228
229
it('will trigger reload if the same page is loaded again', async () => {
230
let counter = 0;
231
232
koaServer.post('/postback', ctx => {
233
ctx.redirect('/postback');
234
});
235
236
koaServer.get('/postback', ctx => {
237
if (counter === 0) {
238
ctx.body = `
239
<body>
240
<h1>Hi</h1>
241
<form action="/postback" method="post">
242
<input type="submit" name="submit">
243
</form>
244
</body>
245
`;
246
} else {
247
ctx.body = `<body><h1>Loaded</h1></body>`;
248
}
249
counter += 1;
250
});
251
const agent = await handler.createAgent();
252
await agent.goto(`${koaServer.baseUrl}/postback`);
253
await agent.click(agent.activeTab.document.querySelector('input'));
254
255
await expect(agent.waitForLocation('reload')).resolves.toBeTruthy();
256
});
257
});
258
259