Skip to content

Commit 31a05d6

Browse files
[test optimization] Fix disable logic in playwright (#6954)
1 parent 2fd9b1d commit 31a05d6

File tree

4 files changed

+145
-9
lines changed

4 files changed

+145
-9
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
'use strict'
2+
3+
/* eslint-disable no-console */
4+
5+
const { test, expect } = require('@playwright/test')
6+
7+
test.beforeEach(async ({ page }) => {
8+
await page.goto(process.env.PW_BASE_URL)
9+
})
10+
11+
test.describe('disable', () => {
12+
test('should disable test', async ({ page }) => {
13+
console.log('SHOULD NOT BE EXECUTED')
14+
await expect(page.locator('.hello-world')).toHaveText([
15+
'Hello Warld'
16+
])
17+
})
18+
})
19+
20+
test.describe('not disabled', () => {
21+
test('should not disable test', async ({ page }) => {
22+
await expect(page.locator('.hello-world')).toHaveText([
23+
'Hello World'
24+
])
25+
})
26+
})
27+
28+
test.describe('not disabled 2', () => {
29+
test('should not disable test 2', async ({ page }) => {
30+
await expect(page.locator('.hello-world')).toHaveText([
31+
'Hello World'
32+
])
33+
})
34+
})
35+
36+
test.describe('not disabled 3', () => {
37+
test('should not disable test 3', async ({ page }) => {
38+
await expect(page.locator('.hello-world')).toHaveText([
39+
'Hello World'
40+
])
41+
})
42+
})

integration-tests/ci-visibility/playwright-tests-test-management/disabled-test.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
'use strict'
22

3+
/* eslint-disable no-console */
4+
35
const { test, expect } = require('@playwright/test')
46

57
test.beforeEach(async ({ page }) => {
@@ -8,8 +10,33 @@ test.beforeEach(async ({ page }) => {
810

911
test.describe('disable', () => {
1012
test('should disable test', async ({ page }) => {
13+
console.log('SHOULD NOT BE EXECUTED')
1114
await expect(page.locator('.hello-world')).toHaveText([
1215
'Hello Warld'
1316
])
1417
})
1518
})
19+
20+
test.describe('not disabled', () => {
21+
test('should not disable test', async ({ page }) => {
22+
await expect(page.locator('.hello-world')).toHaveText([
23+
'Hello World'
24+
])
25+
})
26+
})
27+
28+
test.describe('not disabled 2', () => {
29+
test('should not disable test 2', async ({ page }) => {
30+
await expect(page.locator('.hello-world')).toHaveText([
31+
'Hello World'
32+
])
33+
})
34+
})
35+
36+
test.describe('not disabled 3', () => {
37+
test('should not disable test 3', async ({ page }) => {
38+
await expect(page.locator('.hello-world')).toHaveText([
39+
'Hello World'
40+
])
41+
})
42+
})

integration-tests/playwright/playwright.spec.js

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,7 +1352,9 @@ versions.forEach((version) => {
13521352
})
13531353

13541354
context('disabled', () => {
1355+
let testOutput = ''
13551356
beforeEach(() => {
1357+
testOutput = ''
13561358
receiver.setTestManagementTests({
13571359
playwright: {
13581360
suites: {
@@ -1364,6 +1366,15 @@ versions.forEach((version) => {
13641366
}
13651367
}
13661368
}
1369+
},
1370+
'disabled-2-test.js': {
1371+
tests: {
1372+
'disable should disable test': {
1373+
properties: {
1374+
disabled: true
1375+
}
1376+
}
1377+
}
13671378
}
13681379
}
13691380
}
@@ -1375,29 +1386,47 @@ versions.forEach((version) => {
13751386
.gatherPayloadsMaxTimeout(({ url }) => url === '/api/v2/citestcycle', (payloads) => {
13761387
const events = payloads.flatMap(({ payload }) => payload.events)
13771388

1389+
const resourceNames = events.filter(event => event.type === 'test').map(event => event.content.resource)
1390+
assert.includeMembers(resourceNames, [
1391+
'disabled-test.js.disable should disable test',
1392+
'disabled-test.js.not disabled should not disable test',
1393+
'disabled-test.js.not disabled 2 should not disable test 2',
1394+
'disabled-test.js.not disabled 3 should not disable test 3',
1395+
'disabled-2-test.js.disable should disable test',
1396+
'disabled-2-test.js.not disabled should not disable test',
1397+
'disabled-2-test.js.not disabled 2 should not disable test 2',
1398+
'disabled-2-test.js.not disabled 3 should not disable test 3',
1399+
])
1400+
13781401
const testSession = events.find(event => event.type === 'test_session_end').content
13791402
if (isDisabling) {
13801403
assert.propertyVal(testSession.meta, TEST_MANAGEMENT_ENABLED, 'true')
13811404
} else {
13821405
assert.notProperty(testSession.meta, TEST_MANAGEMENT_ENABLED)
13831406
}
13841407

1385-
const skippedTest = events.find(event => event.type === 'test').content
1408+
const tests = events.filter(event => event.type === 'test').map(event => event.content)
1409+
assert.equal(tests.length, 8)
13861410

1387-
if (isDisabling) {
1388-
assert.equal(skippedTest.meta[TEST_STATUS], 'skip')
1389-
assert.propertyVal(skippedTest.meta, TEST_MANAGEMENT_IS_DISABLED, 'true')
1390-
} else {
1391-
assert.equal(skippedTest.meta[TEST_STATUS], 'fail')
1392-
assert.notProperty(skippedTest.meta, TEST_MANAGEMENT_IS_DISABLED)
1393-
}
1411+
const disabledTests = tests.filter(test => test.meta[TEST_NAME] === 'disable should disable test')
1412+
assert.equal(disabledTests.length, 2)
1413+
1414+
disabledTests.forEach(test => {
1415+
if (isDisabling) {
1416+
assert.equal(test.meta[TEST_STATUS], 'skip')
1417+
assert.propertyVal(test.meta, TEST_MANAGEMENT_IS_DISABLED, 'true')
1418+
} else {
1419+
assert.equal(test.meta[TEST_STATUS], 'fail')
1420+
assert.notProperty(test.meta, TEST_MANAGEMENT_IS_DISABLED)
1421+
}
1422+
})
13941423
}, 25000)
13951424

13961425
const runDisableTest = async (isDisabling, extraEnvVars) => {
13971426
const testAssertionsPromise = getTestAssertions(isDisabling)
13981427

13991428
childProcess = exec(
1400-
'./node_modules/.bin/playwright test -c playwright.config.js disabled-test.js',
1429+
'./node_modules/.bin/playwright test -c playwright.config.js disabled-test.js disabled-2-test.js',
14011430
{
14021431
cwd,
14031432
env: {
@@ -1410,14 +1439,26 @@ versions.forEach((version) => {
14101439
}
14111440
)
14121441

1442+
childProcess.stdout.on('data', (chunk) => {
1443+
testOutput += chunk.toString()
1444+
})
1445+
childProcess.stderr.on('data', (chunk) => {
1446+
testOutput += chunk.toString()
1447+
})
1448+
14131449
const [[exitCode]] = await Promise.all([
14141450
once(childProcess, 'exit'),
1451+
once(childProcess.stdout, 'end'),
1452+
once(childProcess.stderr, 'end'),
14151453
testAssertionsPromise
14161454
])
14171455

1456+
// the testOutput checks whether the test is actually skipped
14181457
if (isDisabling) {
1458+
assert.notInclude(testOutput, 'SHOULD NOT BE EXECUTED')
14191459
assert.equal(exitCode, 0)
14201460
} else {
1461+
assert.include(testOutput, 'SHOULD NOT BE EXECUTED')
14211462
assert.equal(exitCode, 1)
14221463
}
14231464
}
@@ -1428,6 +1469,12 @@ versions.forEach((version) => {
14281469
await runDisableTest(true)
14291470
})
14301471

1472+
it('can disable tests in fullyParallel mode', async () => {
1473+
receiver.setSettings({ test_management: { enabled: true } })
1474+
1475+
await runDisableTest(true, { FULLY_PARALLEL: true, PLAYWRIGHT_WORKERS: '3' })
1476+
})
1477+
14311478
it('fails if disable is not enabled', async () => {
14321479
receiver.setSettings({ test_management: { enabled: false } })
14331480

packages/datadog-instrumentations/src/playwright.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,15 @@ function dispatcherRunWrapper (run) {
481481

482482
function dispatcherRunWrapperNew (run) {
483483
return function (testGroups) {
484+
// Filter out disabled tests from testGroups before they get scheduled
485+
if (isTestManagementTestsEnabled) {
486+
testGroups.forEach(group => {
487+
group.tests = group.tests.filter(test => !test._ddIsDisabled)
488+
})
489+
// Remove empty groups
490+
testGroups = testGroups.filter(group => group.tests.length > 0)
491+
}
492+
484493
if (!this._allTests) {
485494
// Removed in https://github.com/microsoft/playwright/commit/1e52c37b254a441cccf332520f60225a5acc14c7
486495
// Not available from >=1.44.0
@@ -893,6 +902,9 @@ addHook({
893902
if (testProperties.disabled) {
894903
test._ddIsDisabled = true
895904
test.expectedStatus = 'skipped'
905+
// setting test.expectedStatus to 'skipped' does not work for every case,
906+
// so we need to filter out disabled tests in dispatcherRunWrapperNew,
907+
// so they don't get to the workers
896908
continue
897909
}
898910
if (testProperties.quarantined) {
@@ -1270,6 +1282,10 @@ function generateSummaryWrapper (generateSummary) {
12701282
const {
12711283
_requireFile: testSuiteAbsolutePath,
12721284
location: { line: testSourceLine },
1285+
_ddIsNew: isNew,
1286+
_ddIsDisabled: isDisabled,
1287+
_ddIsModified: isModified,
1288+
_ddIsQuarantined: isQuarantined
12731289
} = test
12741290
const browserName = getBrowserNameFromProjects(sessionProjects, test)
12751291

@@ -1278,6 +1294,10 @@ function generateSummaryWrapper (generateSummary) {
12781294
testSuiteAbsolutePath,
12791295
testSourceLine,
12801296
browserName,
1297+
isNew,
1298+
isDisabled,
1299+
isModified,
1300+
isQuarantined
12811301
})
12821302
}
12831303
}

0 commit comments

Comments
 (0)