Skip to content

Commit

Permalink
tests: remove usages of legacy driver (#15230)
Browse files Browse the repository at this point in the history
  • Loading branch information
adamraine authored Jul 7, 2023
1 parent 85ced34 commit 9fd24a3
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 186 deletions.
78 changes: 28 additions & 50 deletions core/test/gather/driver/execution-context-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,28 @@

import {ExecutionContext} from '../../../gather/driver/execution-context.js';
import {
mockCommands,
makePromiseInspectable,
flushAllTimersAndMicrotasks,
fnAny,
timers,
} from '../../test-utils.js';

// This can be removed when FR becomes the default.
const createMockSendCommandFn =
mockCommands.createMockSendCommandFn.bind(null, {useSessionId: false});

/** @return {LH.Gatherer.FRProtocolSession} */
function createMockSession() {
/** @type {any} */
const session = {};
session.hasNextProtocolTimeout = fnAny().mockReturnValue(false);
session.setNextProtocolTimeout = fnAny();
return session;
}
import {createMockSession} from '../mock-driver.js';

/** @param {string} s */
function trimTrailingWhitespace(s) {
return s.split('\n').map(line => line.trimEnd()).join('\n');
}

describe('ExecutionContext', () => {
/** @type {LH.Gatherer.FRProtocolSession} */
let sessionMock;
let sessionMock = createMockSession();
/** @type {(executionContext: ExecutionContext, id: number) => Promise<void>} */
let forceNewContextId;

beforeEach(() => {
sessionMock = createMockSession();

forceNewContextId = async (executionContext, executionContextId) => {
executionContext._session.sendCommand = createMockSendCommandFn()
sessionMock.sendCommand
.mockResponse('Page.enable')
.mockResponse('Runtime.enable')
.mockResponse('Page.getFrameTree', {frameTree: {frame: {id: '1337'}}})
Expand All @@ -53,11 +39,9 @@ describe('ExecutionContext', () => {
});

it('should clear context on frame navigations', async () => {
const onMock = sessionMock.on = fnAny();

const executionContext = new ExecutionContext(sessionMock);

const frameListener = onMock.mock.calls.find(call => call[0] === 'Page.frameNavigated');
const frameListener = sessionMock.on.mock.calls.find(call => call[0] === 'Page.frameNavigated');
expect(frameListener).toBeDefined();

await forceNewContextId(executionContext, 42);
Expand All @@ -67,11 +51,9 @@ describe('ExecutionContext', () => {
});

it('should clear context on execution context destroyed', async () => {
const onMock = sessionMock.on = fnAny();

const executionContext = new ExecutionContext(sessionMock);

const executionDestroyed = onMock.mock.calls
const executionDestroyed = sessionMock.on.mock.calls
.find(call => call[0] === 'Runtime.executionContextDestroyed');
expect(executionDestroyed).toBeDefined();

Expand All @@ -90,19 +72,17 @@ describe('.evaluateAsync', () => {
before(() => timers.useFakeTimers());
after(() => timers.dispose());

/** @type {LH.Gatherer.FRProtocolSession} */
let sessionMock;
let sessionMock = createMockSession();
/** @type {ExecutionContext} */
let executionContext;

beforeEach(() => {
sessionMock = createMockSession();
sessionMock.on = fnAny();
executionContext = new ExecutionContext(sessionMock);
executionContext = new ExecutionContext(sessionMock.asSession());
});

it('evaluates an expression', async () => {
const sendCommand = (sessionMock.sendCommand = createMockSendCommandFn().mockResponse(
const sendCommand = (sessionMock.sendCommand.mockResponse(
'Runtime.evaluate',
{result: {value: 2}}
));
Expand All @@ -115,7 +95,7 @@ describe('.evaluateAsync', () => {
it('uses a high default timeout', async () => {
const setNextProtocolTimeout = sessionMock.setNextProtocolTimeout = fnAny();
sessionMock.hasNextProtocolTimeout = fnAny().mockReturnValue(false);
sessionMock.sendCommand = createMockSendCommandFn().mockRejectedValue(new Error('Timeout'));
sessionMock.sendCommand.mockRejectedValue(new Error('Timeout'));

const evaluatePromise = makePromiseInspectable(executionContext.evaluateAsync('1 + 1'));

Expand All @@ -130,7 +110,7 @@ describe('.evaluateAsync', () => {
const setNextProtocolTimeout = sessionMock.setNextProtocolTimeout = fnAny();
sessionMock.hasNextProtocolTimeout = fnAny().mockReturnValue(true);
sessionMock.getNextProtocolTimeout = fnAny().mockReturnValue(expectedTimeout);
sessionMock.sendCommand = createMockSendCommandFn().mockRejectedValue(new Error('Timeout'));
sessionMock.sendCommand.mockRejectedValue(new Error('Timeout'));

const evaluatePromise = makePromiseInspectable(executionContext.evaluateAsync('1 + 1'));

Expand All @@ -141,38 +121,38 @@ describe('.evaluateAsync', () => {
});

it('evaluates an expression in isolation', async () => {
let sendCommand = (sessionMock.sendCommand = createMockSendCommandFn()
sessionMock.sendCommand
.mockResponse('Page.enable')
.mockResponse('Runtime.enable')
.mockResponse('Page.getFrameTree', {frameTree: {frame: {id: '1337'}}})
.mockResponse('Page.createIsolatedWorld', {executionContextId: 1})
.mockResponse('Runtime.evaluate', {result: {value: 2}}));
.mockResponse('Runtime.evaluate', {result: {value: 2}})
.mockResponse('Runtime.evaluate', {result: {value: 2}});

const value = await executionContext.evaluateAsync('1 + 1', {useIsolation: true});
expect(value).toEqual(2);

// Check that we used the correct frame when creating the isolated context
const createWorldArgs = sendCommand.findInvocation('Page.createIsolatedWorld');
expect(createWorldArgs).toMatchObject({frameId: '1337'});
let createWorldInvocations =
sessionMock.sendCommand.findAllInvocations('Page.createIsolatedWorld');
expect(createWorldInvocations[0]).toMatchObject({frameId: '1337'});

// Check that we used the isolated context when evaluating
const evaluateArgs = sendCommand.findInvocation('Runtime.evaluate');
const evaluateArgs = sessionMock.sendCommand.findInvocation('Runtime.evaluate');
expect(evaluateArgs).toMatchObject({contextId: 1});

// Make sure we cached the isolated context from last time
sendCommand = sessionMock.sendCommand = createMockSendCommandFn().mockResponse(
'Runtime.evaluate',
{result: {value: 2}}
);
createWorldInvocations = sessionMock.sendCommand.findAllInvocations('Page.createIsolatedWorld');
expect(createWorldInvocations).toHaveLength(1);

await executionContext.evaluateAsync('1 + 1', {useIsolation: true});
expect(sessionMock.sendCommand).not.toHaveBeenCalledWith(
'Page.createIsolatedWorld',
expect.anything()
);

createWorldInvocations = sessionMock.sendCommand.findAllInvocations('Page.createIsolatedWorld');
expect(createWorldInvocations).toHaveLength(1);
});

it('recovers from isolation failures', async () => {
sessionMock.sendCommand = createMockSendCommandFn()
sessionMock.sendCommand
.mockResponse('Page.enable')
.mockResponse('Runtime.enable')
.mockResponse('Page.getFrameTree', {frameTree: {frame: {id: '1337'}}})
Expand Down Expand Up @@ -205,7 +185,7 @@ describe('.evaluateAsync', () => {
' at _lighthouse-eval.js:83:8',
},
};
sessionMock.sendCommand = createMockSendCommandFn()
sessionMock.sendCommand
.mockResponse('Page.enable')
.mockResponse('Runtime.enable')
.mockResponse('Page.getResourceTree', {frameTree: {frame: {id: '1337'}}})
Expand All @@ -221,19 +201,17 @@ describe('.evaluateAsync', () => {
});

describe('.evaluate', () => {
/** @type {LH.Gatherer.FRProtocolSession} */
let sessionMock;
let sessionMock = createMockSession();
/** @type {ExecutionContext} */
let executionContext;

beforeEach(() => {
sessionMock = createMockSession();
sessionMock.on = fnAny();
executionContext = new ExecutionContext(sessionMock);
executionContext = new ExecutionContext(sessionMock.asSession());
});

it('transforms parameters into an expression given to Runtime.evaluate', async () => {
const mockFn = sessionMock.sendCommand = createMockSendCommandFn()
const mockFn = sessionMock.sendCommand
.mockResponse('Runtime.evaluate', {result: {value: 1}});

/** @param {number} value */
Expand Down
19 changes: 8 additions & 11 deletions core/test/gather/driver/navigation-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,11 @@

import {createMockDriver} from '../mock-driver.js';
import {
mockCommands,
makePromiseInspectable,
flushAllTimersAndMicrotasks,
timers,
} from '../../test-utils.js';

const {createMockOnceFn} = mockCommands;

// Some imports needs to be done dynamically, so that their dependencies will be mocked.
// https://github.com/GoogleChrome/lighthouse/blob/main/docs/hacking-tips.md#mocking-modules-with-testdouble
const {gotoURL, getNavigationWarnings} = await import('../../../gather/driver/navigation.js');
Expand Down Expand Up @@ -41,7 +38,7 @@ describe('.gotoURL', () => {
});

it('will track redirects through gotoURL load with warning', async () => {
mockDriver.defaultSession.on = mockDriver.defaultSession.once = createMockOnceFn();
mockDriver.defaultSession.on = mockDriver.defaultSession.once;

const url = 'http://example.com';

Expand Down Expand Up @@ -93,7 +90,7 @@ describe('.gotoURL', () => {
});

it('backfills requestedUrl when using a callback requestor', async () => {
mockDriver.defaultSession.on = mockDriver.defaultSession.once = createMockOnceFn();
mockDriver.defaultSession.on = mockDriver.defaultSession.once;

const requestor = () => Promise.resolve();

Expand All @@ -112,7 +109,7 @@ describe('.gotoURL', () => {
});

it('throws if no navigations found using a callback requestor', async () => {
mockDriver.defaultSession.on = mockDriver.defaultSession.once = createMockOnceFn();
mockDriver.defaultSession.on = mockDriver.defaultSession.once;

const requestor = () => Promise.resolve();

Expand All @@ -131,7 +128,7 @@ describe('.gotoURL', () => {
});

it('does not add warnings when URLs are equal', async () => {
mockDriver.defaultSession.on = mockDriver.defaultSession.once = createMockOnceFn();
mockDriver.defaultSession.on = mockDriver.defaultSession.once;

const url = 'https://www.example.com';

Expand All @@ -147,7 +144,7 @@ describe('.gotoURL', () => {
});

it('waits for Page.frameNavigated', async () => {
mockDriver.defaultSession.on = mockDriver.defaultSession.once = createMockOnceFn();
mockDriver.defaultSession.on = mockDriver.defaultSession.once;

const url = 'https://www.example.com';

Expand All @@ -165,7 +162,7 @@ describe('.gotoURL', () => {
});

it('waits for page load', async () => {
mockDriver.defaultSession.on = mockDriver.defaultSession.once = createMockOnceFn();
mockDriver.defaultSession.on = mockDriver.defaultSession.once;

const url = 'https://www.example.com';

Expand Down Expand Up @@ -194,7 +191,7 @@ describe('.gotoURL', () => {
});

it('waits for page FCP', async () => {
mockDriver.defaultSession.on = mockDriver.defaultSession.once = createMockOnceFn();
mockDriver.defaultSession.on = mockDriver.defaultSession.once;

const url = 'https://www.example.com';

Expand Down Expand Up @@ -228,7 +225,7 @@ describe('.gotoURL', () => {
});

it('throws when asked to wait for FCP without waiting for load', async () => {
mockDriver.defaultSession.on = mockDriver.defaultSession.once = createMockOnceFn();
mockDriver.defaultSession.on = mockDriver.defaultSession.once;

const url = 'https://www.example.com';

Expand Down
21 changes: 2 additions & 19 deletions core/test/gather/driver/wait-for-condition-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,13 @@ import log from 'lighthouse-logger';

import * as wait from '../../../gather/driver/wait-for-condition.js';
import {
mockCommands,
makePromiseInspectable,
flushAllTimersAndMicrotasks,
createDecomposedPromise,
fnAny,
timers,
} from '../../test-utils.js';

const {createMockOnceFn} = mockCommands;

import {createMockSession} from '../mock-driver.js';

function createMockWaitForFn() {
const {promise, resolve, reject} = createDecomposedPromise();
Expand Down Expand Up @@ -256,18 +253,11 @@ describe('waitForFcp()', () => {
let session;

beforeEach(() => {
session = {
on: fnAny(),
once: fnAny(),
off: fnAny(),
sendCommand: fnAny(),
};
session = createMockSession();
});


it('should not resolve until FCP fires', async () => {
session.on = session.once = createMockOnceFn();

const waitPromise = makePromiseInspectable(wait.waitForFcp(session, 0, 60 * 1000).promise);
const listener = session.on.findListener('Page.lifecycleEvent');

Expand All @@ -285,8 +275,6 @@ describe('waitForFcp()', () => {
});

it('should wait for pauseAfterFcpMs after FCP', async () => {
session.on = session.once = createMockOnceFn();

const waitPromise = makePromiseInspectable(wait.waitForFcp(session, 5000, 60 * 1000).promise);
const listener = session.on.findListener('Page.lifecycleEvent');

Expand All @@ -305,8 +293,6 @@ describe('waitForFcp()', () => {
});

it('should timeout', async () => {
session.on = session.once = createMockOnceFn();

const waitPromise = makePromiseInspectable(wait.waitForFcp(session, 0, 5000).promise);

await flushAllTimersAndMicrotasks();
Expand All @@ -319,9 +305,6 @@ describe('waitForFcp()', () => {
});

it('should be cancellable', async () => {
session.on = session.once = createMockOnceFn();
session.off = fnAny();

const {promise: rawPromise, cancel} = wait.waitForFcp(session, 0, 5000);
const waitPromise = makePromiseInspectable(rawPromise);

Expand Down
15 changes: 5 additions & 10 deletions core/test/gather/gatherers/global-listeners-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
*/

import GlobalListenerGatherer from '../../../gather/gatherers/global-listeners.js';
import {createMockSendCommandFn} from '../mock-commands.js';
import {Connection} from '../../../legacy/gather/connections/connection.js';
import {Driver} from '../../../legacy/gather/driver.js';
import {createMockDriver} from '../mock-driver.js';

describe('Global Listener Gatherer', () => {
it('remove duplicate listeners from artifacts', async () => {
Expand Down Expand Up @@ -39,19 +37,16 @@ describe('Global Listener Gatherer', () => {
},
];

const sendCommandMock = createMockSendCommandFn()
.mockResponse('Runtime.evaluate', {result: {objectId: 10}})
.mockResponse('DOMDebugger.getEventListeners', {listeners: mockListeners.slice(0)});

const expectedOutput = [
mockListeners[0],
mockListeners[2],
mockListeners[3],
];

const connectionStub = new Connection();
connectionStub.sendCommand = sendCommandMock;
const driver = new Driver(connectionStub);
const driver = createMockDriver();
driver._session.sendCommand
.mockResponse('Runtime.evaluate', {result: {objectId: 10}})
.mockResponse('DOMDebugger.getEventListeners', {listeners: mockListeners.slice(0)});

const globalListeners = await globalListenerGatherer.getArtifact({driver});
return expect(globalListeners).toMatchObject(expectedOutput);
Expand Down
Loading

0 comments on commit 9fd24a3

Please sign in to comment.