2020-08-05 02:32:10 +03:00
|
|
|
/**
|
|
|
|
* Copyright 2018 Google Inc. All rights reserved.
|
|
|
|
* Modifications copyright (c) Microsoft Corporation.
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2020-08-20 07:32:12 +03:00
|
|
|
import './playwright.fixtures';
|
2020-08-12 01:50:53 +03:00
|
|
|
import { Frame, Page } from '..';
|
|
|
|
import { TestServer } from '../utils/testserver';
|
2020-08-05 02:32:10 +03:00
|
|
|
|
|
|
|
it('should navigate to empty page with networkidle', async({page, server}) => {
|
|
|
|
const response = await page.goto(server.EMPTY_PAGE, { waitUntil: 'networkidle' });
|
|
|
|
expect(response.status()).toBe(200);
|
|
|
|
});
|
|
|
|
|
2020-08-12 01:50:53 +03:00
|
|
|
async function networkIdleTest(frame: Frame, server: TestServer, action: () => Promise<any>, isSetContent?: boolean) {
|
2020-08-05 02:32:10 +03:00
|
|
|
const finishResponse = response => {
|
|
|
|
response.statusCode = 404;
|
|
|
|
response.end(`File not found`);
|
|
|
|
};
|
|
|
|
const waitForRequest = suffix => {
|
|
|
|
return Promise.all([
|
|
|
|
server.waitForRequest(suffix),
|
2020-08-12 01:50:53 +03:00
|
|
|
(frame['_page'] as Page).waitForRequest(server.PREFIX + suffix),
|
2020-08-05 02:32:10 +03:00
|
|
|
]);
|
|
|
|
}
|
|
|
|
let responses = {};
|
|
|
|
// Hold on to a bunch of requests without answering.
|
2020-08-12 01:50:53 +03:00
|
|
|
server.setRoute('/fetch-request-a.js', (req, res) => responses['a'] = res);
|
2020-08-05 02:32:10 +03:00
|
|
|
const firstFetchResourceRequested = waitForRequest('/fetch-request-a.js');
|
2020-08-12 01:50:53 +03:00
|
|
|
server.setRoute('/fetch-request-d.js', (req, res) => responses['d'] = res);
|
2020-08-05 02:32:10 +03:00
|
|
|
const secondFetchResourceRequested = waitForRequest('/fetch-request-d.js');
|
|
|
|
|
|
|
|
const waitForLoadPromise = isSetContent ? Promise.resolve() : frame.waitForNavigation({ waitUntil: 'load' });
|
|
|
|
|
|
|
|
// Navigate to a page which loads immediately and then does a bunch of
|
|
|
|
// requests via javascript's fetch method.
|
|
|
|
const actionPromise = action();
|
|
|
|
|
|
|
|
// Track when the action gets completed.
|
|
|
|
let actionFinished = false;
|
|
|
|
actionPromise.then(() => actionFinished = true);
|
|
|
|
|
|
|
|
// Wait for the frame's 'load' event.
|
|
|
|
await waitForLoadPromise;
|
|
|
|
expect(actionFinished).toBe(false);
|
|
|
|
|
|
|
|
// Wait for the initial resource to be requested.
|
|
|
|
await firstFetchResourceRequested;
|
|
|
|
expect(actionFinished).toBe(false);
|
|
|
|
|
2020-08-12 01:50:53 +03:00
|
|
|
expect(responses['a']).toBeTruthy();
|
2020-08-05 02:32:10 +03:00
|
|
|
let timer;
|
|
|
|
let timerTriggered = false;
|
|
|
|
// Finishing response should trigger the second round.
|
2020-08-12 01:50:53 +03:00
|
|
|
finishResponse(responses['a']);
|
2020-08-05 02:32:10 +03:00
|
|
|
|
|
|
|
// Wait for the second round to be requested.
|
|
|
|
await secondFetchResourceRequested;
|
|
|
|
expect(actionFinished).toBe(false);
|
|
|
|
// Finishing the last response should trigger networkidle.
|
|
|
|
timer = setTimeout(() => timerTriggered = true, 500);
|
2020-08-12 01:50:53 +03:00
|
|
|
finishResponse(responses['d']);
|
2020-08-05 02:32:10 +03:00
|
|
|
|
|
|
|
const response = await actionPromise;
|
|
|
|
clearTimeout(timer);
|
|
|
|
expect(timerTriggered).toBe(true);
|
|
|
|
if (!isSetContent)
|
|
|
|
expect(response.ok()).toBe(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
it('should wait for networkidle to succeed navigation', async({page, server}) => {
|
|
|
|
await networkIdleTest(page.mainFrame(), server, () => {
|
|
|
|
return page.goto(server.PREFIX + '/networkidle.html', { waitUntil: 'networkidle' });
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should wait for networkidle to succeed navigation with request from previous navigation', async({page, server}) => {
|
|
|
|
await page.goto(server.EMPTY_PAGE);
|
|
|
|
server.setRoute('/foo.js', () => {});
|
|
|
|
await page.setContent(`<script>fetch('foo.js');</script>`);
|
|
|
|
await networkIdleTest(page.mainFrame(), server, () => {
|
|
|
|
return page.goto(server.PREFIX + '/networkidle.html', { waitUntil: 'networkidle' });
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should wait for networkidle in waitForNavigation', async({page, server}) => {
|
|
|
|
await networkIdleTest(page.mainFrame(), server, () => {
|
|
|
|
const promise = page.waitForNavigation({ waitUntil: 'networkidle' });
|
|
|
|
page.goto(server.PREFIX + '/networkidle.html');
|
|
|
|
return promise;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should wait for networkidle in setContent', async({page, server}) => {
|
|
|
|
await page.goto(server.EMPTY_PAGE);
|
|
|
|
await networkIdleTest(page.mainFrame(), server, () => {
|
|
|
|
return page.setContent(`<script src='networkidle.js'></script>`, { waitUntil: 'networkidle' });
|
|
|
|
}, true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should wait for networkidle in setContent with request from previous navigation', async({page, server}) => {
|
|
|
|
await page.goto(server.EMPTY_PAGE);
|
|
|
|
server.setRoute('/foo.js', () => {});
|
|
|
|
await page.setContent(`<script>fetch('foo.js');</script>`);
|
|
|
|
await networkIdleTest(page.mainFrame(), server, () => {
|
|
|
|
return page.setContent(`<script src='networkidle.js'></script>`, { waitUntil: 'networkidle' });
|
|
|
|
}, true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should wait for networkidle when navigating iframe', async({page, server}) => {
|
|
|
|
await page.goto(server.PREFIX + '/frames/one-frame.html');
|
|
|
|
const frame = page.mainFrame().childFrames()[0];
|
|
|
|
await networkIdleTest(frame, server, () => frame.goto(server.PREFIX + '/networkidle.html', { waitUntil: 'networkidle' }));
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should wait for networkidle in setContent from the child frame', async({page, server}) => {
|
|
|
|
await page.goto(server.EMPTY_PAGE);
|
|
|
|
await networkIdleTest(page.mainFrame(), server, () => {
|
|
|
|
return page.setContent(`<iframe src='networkidle.html'></iframe>`, { waitUntil: 'networkidle' });
|
|
|
|
}, true);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should wait for networkidle from the child frame', async({page, server}) => {
|
|
|
|
await networkIdleTest(page.mainFrame(), server, () => {
|
|
|
|
return page.goto(server.PREFIX + '/networkidle-frame.html', { waitUntil: 'networkidle' });
|
|
|
|
});
|
|
|
|
});
|