Lint against screenshot tests outside perf panel interaction test base

A new rule is added that checks that calls to itScreenshot are only made
within the newly added directory for the Performance Panel interactions
tests. This plus the rule that ensures screenshots are asserted in an
itScreenshot block, restrict using the screenshot test API outside of
the mentioned directory.

Bug: 1407638
Change-Id: I6cff308e9c150bfa231bd65b6190aa293273910a
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/4207836
Commit-Queue: Andres Olivares <andoli@chromium.org>
Reviewed-by: Jack Franklin <jacktfranklin@chromium.org>
This commit is contained in:
Andrés Olivares
2023-01-31 15:01:42 +00:00
committed by Devtools-frontend LUCI CQ
parent 1ec35fcf3e
commit b0384e77be
3 changed files with 145 additions and 0 deletions
@@ -0,0 +1,44 @@
// Copyright 2023 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
'use strict';
const path = require('path');
const PERFOMANCE_PANEL_INTERACTION_TESTS_PATH =
path.join(__dirname, '..', '..', '..', 'test', 'interactions', 'panels', 'performance');
module.exports = {
meta : {
type : 'problem',
docs : {
description : 'Bans writting screenshot tests outside the directory for the Performance Panel interaction tests.',
category : 'Possible Errors',
},
fixable : 'code',
messages : {
invalidScreenshotTest : 'It is banned to write screenshot tests outside the directory of the Performance Panel interaction tests.',
},
schema : []
},
create : function(context) {
const fileName = path.resolve(context.getFilename());
function reportPathIfInvalid(node) {
if(!fileName.includes(PERFOMANCE_PANEL_INTERACTION_TESTS_PATH)) {
context.report({
node,
messageId: 'invalidScreenshotTest'
});
}
}
return {
'CallExpression[callee.type="Identifier"][callee.name="itScreenshot"], MemberExpression'(node) {
const isScreenshotTest = node.type === 'CallExpression';
const isSkippedScreenshotTest = (node.property?.name === 'skip' && node.object?.name === 'itScreenshot' );
if (isScreenshotTest || isSkippedScreenshotTest) {
reportPathIfInvalid(node);
}
},
};
}
};
@@ -0,0 +1,100 @@
// Copyright 2023 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
'use strict';
const rule = require('../lib/ban_screenshot_test_outside_perf_panel.js');
const ruleTester = new (require('eslint').RuleTester)({
parserOptions: {ecmaVersion: 9, sourceType: 'module'},
});
const EXPECTED_ERROR_MESSAGE =
'It is banned to write screenshot tests outside the directory of the Performance Panel interaction tests.';
const enabledTestCode = `describe('Performance panel', () => {
itScreenshot('renders the timeline correctly', async () => {
await loadComponentDocExample('performance_panel/basic.html?trace=animation');
await waitFor('#timeline-overview-panel');
const panel = await waitFor('body');
await assertElementScreenshotUnchanged(panel, 'performance/timeline.png');
});
});`;
const disabledTestCode = `describe('Performance panel', () => {
// Disabled until screenshot tests infrastructure is available in DevTools bots.
itScreenshot.skip('[crbug.com/1407638] renders the timeline correctly', async () => {
await waitFor('#timeline-overview-panel');
const panel = await waitFor('body');
await assertElementScreenshotUnchanged(panel, 'performance/timeline.png');
});
});`;
const notAScreenshotTestCode = `describe('Performance panel', () => {
it('renders the timeline correctly', async () => {
await waitFor('#timeline-overview-panel');
const panel = await waitFor('body');
await assertElementScreenshotUnchanged(panel, 'performance/timeline.png');
});
});`;
const notAScreenshotTestDisabledCode = `describe('Performance panel', () => {
// This is disabled.
it.skip('[crbug.com/1407638] renders the timeline correctly', async () => {
await waitFor('#timeline-overview-panel');
const panel = await waitFor('body');
await assertElementScreenshotUnchanged(panel, 'performance/timeline.png');
});
});`;
const perfPanelInteractionTestsPath = 'test/interactions/panels/performance/';
const notPerfPanelTestPath = 'test/interactions/data_grid/data_grid_test.ts';
ruleTester.run('ban_screenshot_test_outside_perf_panel', rule, {
valid: [
{
code: enabledTestCode,
filename: `${perfPanelInteractionTestsPath}timeline/timeline_test.ts`,
},
{
code: disabledTestCode,
filename: `${perfPanelInteractionTestsPath}timeline/timeline_test.ts`,
},
{
code: enabledTestCode,
filename: `${perfPanelInteractionTestsPath}user_timings/user_imings_test.ts`,
},
{
code: disabledTestCode,
filename: `${perfPanelInteractionTestsPath}user_timings/user_imings_test.ts`,
},
{
code: notAScreenshotTestCode,
filename: notPerfPanelTestPath,
},
{
code: notAScreenshotTestDisabledCode,
filename: notPerfPanelTestPath,
},
{
code: notAScreenshotTestDisabledCode,
filename: `${perfPanelInteractionTestsPath}timeline/timeline_test.ts`,
},
],
invalid: [
{
code: enabledTestCode,
filename: notPerfPanelTestPath,
errors: [{message: EXPECTED_ERROR_MESSAGE}],
},
{
code: disabledTestCode,
filename: notPerfPanelTestPath,
errors: [{message: EXPECTED_ERROR_MESSAGE}],
},
{
code: enabledTestCode,
filename: 'test/unittests/front_end/panels/performance/timeline_test.ts',
errors: [{message: EXPECTED_ERROR_MESSAGE}],
},
]
});
+1
View File
@@ -17,6 +17,7 @@ module.exports = {
'rulesdir/avoid_assert_equal' : 2,
'rulesdir/no_repeated_tests' : 2,
'rulesdir/compare_arrays_with_assert_deepequal' : 2,
'rulesdir/ban_screenshot_test_outside_perf_panel' : 2,
},
'overrides' : [{
'files' : ['*.ts'],