Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fixed incorrect Page URL visited when running tests in parallel in one file with Role #6782

Merged
merged 10 commits into from Dec 27, 2021
15 changes: 13 additions & 2 deletions src/role/role.ts
Expand Up @@ -6,11 +6,15 @@ import nanoid from 'nanoid';
import TestRun from '../test-run';
import TestCafeErrorList from '../errors/error-list';

export interface RedirectUrl {
[testId: string]: string;
}

export default class Role extends EventEmitter {
public id: string;
public phase: RolePhase;
public loginUrl: string | null;
public redirectUrl: string | null;
public redirectUrl: RedirectUrl | string | null;
public _initFn: Function | null;
public opts: RoleOptions;
public initErr: null | Error | TestCafeErrorList;
Expand Down Expand Up @@ -99,7 +103,14 @@ export default class Role extends EventEmitter {
}

public async setCurrentUrlAsRedirectUrl (testRun: TestRun): Promise<void> {
this.redirectUrl = await testRun.getCurrentUrl();
const currentUrl = await testRun.getCurrentUrl();

if (this.opts.preserveUrl)
this.redirectUrl = currentUrl;
else {
this.redirectUrl = this.redirectUrl || {};
(this.redirectUrl as RedirectUrl)[testRun.test.id] = currentUrl;
}

await testRun.compilerService?.updateRoleProperty({
roleId: this.id,
Expand Down
8 changes: 6 additions & 2 deletions src/test-run/bookmark.ts
Expand Up @@ -13,7 +13,7 @@ import {
import { CurrentIframeNotFoundError, CurrentIframeIsNotLoadedError } from '../errors/test-run';
import TestRun from './index';
import { ExecuteClientFunctionCommand, ExecuteSelectorCommand } from './commands/observation';
import Role from '../role/role';
import Role, { RedirectUrl } from '../role/role';
import { DEFAULT_SPEED_VALUE } from '../configuration/default-values';
import BrowserConsoleMessages from './browser-console-messages';
import { CommandBase } from './commands/base';
Expand Down Expand Up @@ -158,7 +158,11 @@ export default class TestRunBookmark {

const preserveUrl = this.role.opts.preserveUrl;

await this._restorePage(this.role.redirectUrl as string, stateSnapshot);
const redirectUrl = preserveUrl
? this.role.redirectUrl as string
: (this.role.redirectUrl as RedirectUrl)[this.testRun.test.id];

await this._restorePage(redirectUrl, stateSnapshot);

if (!preserveUrl)
await this._restoreWorkingFrame();
Expand Down
10 changes: 10 additions & 0 deletions test/functional/fixtures/concurrency/pages/first-page.html
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>First page</h1>
</body>
</html>
10 changes: 10 additions & 0 deletions test/functional/fixtures/concurrency/pages/second-page.html
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Second page</h1>
</body>
</html>
5 changes: 5 additions & 0 deletions test/functional/fixtures/concurrency/test-info.js
@@ -0,0 +1,5 @@
const FileStorage = require('../../utils/file-storage');

const testInfo = new FileStorage('test-info.json', __dirname);

module.exports = testInfo;
Aleksey28 marked this conversation as resolved.
Show resolved Hide resolved
19 changes: 14 additions & 5 deletions test/functional/fixtures/concurrency/test.js
Expand Up @@ -3,7 +3,7 @@ const { expect } = require('chai');
const isCI = require('is-ci');
const config = require('../../config');
const { createReporter } = require('../../utils/reporter');
const timeline = require('./timeline');
const testInfo = require('./test-info');


if (config.useLocalBrowsers) {
Expand Down Expand Up @@ -82,20 +82,20 @@ if (config.useLocalBrowsers) {
});

afterEach(() => {
timeline.delete();
testInfo.delete();
});

it('Should run tests sequentially if concurrency = 1', function () {
return run('chrome:headless --no-sandbox', 1, './testcafe-fixtures/sequential-test.js')
.then(() => {
expect(timeline.getData()).eql(['long started', 'long finished', 'short started', 'short finished']);
expect(testInfo.getData()).eql(['long started', 'long finished', 'short started', 'short finished']);
});
});

it('Should run tests concurrently if concurrency > 1', function () {
return run('chrome:headless --no-sandbox', 2, './testcafe-fixtures/concurrent-test.js')
.then(() => {
expect(timeline.getData()).eql(['test started', 'test started', 'short finished', 'long finished']);
expect(testInfo.getData()).eql(['test started', 'test started', 'short finished', 'long finished']);
});
});

Expand All @@ -104,7 +104,7 @@ if (config.useLocalBrowsers) {
it('Should run tests concurrently in different browser kinds', function () {
return run(['chrome:headless --no-sandbox', 'chrome:headless --no-sandbox --user-agent="TestAgent"'], 2, './testcafe-fixtures/multibrowser-concurrent-test.js')
.then(() => {
const timelineData = timeline.getData();
const timelineData = testInfo.getData();

expect(Object.keys(timelineData).length).gt(1);

Expand All @@ -114,6 +114,15 @@ if (config.useLocalBrowsers) {
});
}

if (!config.proxyless) {
it('Should run tests concurrently with Role', function () {
return run('chrome:headless --no-sandbox', 2, './testcafe-fixtures/role-test.js')
.then(() => {
expect(testInfo.getData()).eql(['/fixtures/concurrency/pages/first-page.html', '/fixtures/concurrency/pages/second-page.html']);
});
});
}

it('Should report fixture start correctly if second fixture finishes before first', function () {
return run('chrome:headless --no-sandbox', 2, ['./testcafe-fixtures/multifixture-test-a.js', './testcafe-fixtures/multifixture-test-b.js'], customReporter)
.then(failedCount => {
Expand Down
@@ -1,24 +1,24 @@
import timeline from '../timeline';
import testInfo from '../test-info';

fixture `Concurrent`
.page`../pages/index.html`
.after(() => {
timeline.save();
timeline.clear();
testInfo.save();
testInfo.clear();
});

test('Long test', async t => {
timeline.add('test started');
testInfo.add('test started');

await t.wait(10000);

timeline.add('long finished');
testInfo.add('long finished');
});

test('Short test', async t => {
timeline.add('test started');
testInfo.add('test started');

await t.wait(1000);

timeline.add('short finished');
testInfo.add('short finished');
});
@@ -1,4 +1,4 @@
import timeline from '../timeline';
import testInfo from '../test-info';
import { ClientFunction } from 'testcafe';

const getUserAgent = ClientFunction(() => navigator.userAgent);
Expand All @@ -13,9 +13,9 @@ fixture `Concurrent`
data[t.ctx.userAgent] = [];
})
.after(() => {
timeline.setData(data);
timeline.save();
timeline.clear();
testInfo.setData(data);
testInfo.save();
testInfo.clear();
});

test('Long test', async t => {
Expand Down
@@ -0,0 +1,22 @@
import { Role } from 'testcafe';
import testInfo from '../test-info';

const DEMO_ROLE = Role('http://localhost:3000/fixtures/concurrency/pages/index.html', async () => {
});

fixture`F1`
.beforeEach(async t => {
await t.useRole(DEMO_ROLE);
})
.after(() => {
testInfo.save();
testInfo.clear();
});

test('T1', async (t) => {
testInfo.add(await t.eval(() => window.location.pathname));
}).page('http://localhost:3000/fixtures/concurrency/pages/first-page.html');

test('T2', async (t) => {
testInfo.add(await t.eval(() => window.location.pathname));
}).page('http://localhost:3000/fixtures/concurrency/pages/second-page.html');
@@ -1,24 +1,24 @@
import timeline from '../timeline';
import testInfo from '../test-info';

fixture `Sequential`
.page`../pages/index.html`
.after(() => {
timeline.save();
timeline.clear();
testInfo.save();
testInfo.clear();
});

test('Long test', async t => {
timeline.add('long started');
testInfo.add('long started');

await t.wait(10000);

timeline.add('long finished');
testInfo.add('long finished');
});

test('Short test', async t => {
timeline.add('short started');
testInfo.add('short started');

await t.wait(1000);

timeline.add('short finished');
testInfo.add('short finished');
});
5 changes: 0 additions & 5 deletions test/functional/fixtures/concurrency/timeline.js

This file was deleted.