Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/eslint-plugin-boxel/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module.exports = {
'template-missing-invokable': require('./lib/rules/template-missing-invokable'),
'missing-card-api-import': require('./lib/rules/missing-card-api-import'),
'no-duplicate-imports': require('./lib/rules/no-duplicate-imports'),
'no-percy-direct-import': require('./lib/rules/no-percy-direct-import'),
// Add other rules here
},

Expand Down
1 change: 1 addition & 0 deletions packages/eslint-plugin-boxel/lib/recommended-rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
module.exports = {
"@cardstack/boxel/missing-card-api-import": "error",
"@cardstack/boxel/no-duplicate-imports": "error",
"@cardstack/boxel/no-percy-direct-import": "error",
"@cardstack/boxel/template-missing-invokable": "error"
}
43 changes: 43 additions & 0 deletions packages/eslint-plugin-boxel/lib/rules/no-percy-direct-import.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
'use strict';

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

/** @type {import('eslint').Rule.RuleModule} */
module.exports = {
meta: {
type: 'problem',
docs: {
description:
'Forbid importing percySnapshot directly from @percy/ember; use @cardstack/host/tests/helpers instead',
category: 'Best Practices',
recommended: true,
},
fixable: 'code',
schema: [],
messages: {
noPercyDirectImport:
"Do not import directly from '@percy/ember'. Use `import { percySnapshot } from '@cardstack/host/tests/helpers'` instead.",
},
},

create(context) {
return {
ImportDeclaration(node) {
if (node.source.value === '@percy/ember') {
context.report({
node,
messageId: 'noPercyDirectImport',
fix(fixer) {
return fixer.replaceText(
node,
"import { percySnapshot } from '@cardstack/host/tests/helpers';",
Comment on lines +32 to +35
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Make the autofix safe for non-percySnapshot imports

The rule applies to any ImportDeclaration from @percy/ember, but the autofix always replaces the entire import with import { percySnapshot } .... If a file imports other exports (e.g., import { foo } from '@percy/ember' or import * as percy ...), running eslint --fix will silently drop those imports and change the binding, leading to runtime errors where the original symbols are used. Consider limiting the fixer to cases that actually import percySnapshot (default or named), or remove the autofix and only report.

Useful? React with 👍 / 👎.

);
},
});
}
},
};
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
'use strict';

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

const rule = require('../../../lib/rules/no-percy-direct-import');
const RuleTester = require('eslint').RuleTester;

//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------

const ruleTester = new RuleTester({
parserOptions: {
ecmaVersion: 2022,
sourceType: 'module',
},
});

ruleTester.run('no-percy-direct-import', rule, {
valid: [
{
code: `import { percySnapshot } from '@cardstack/host/tests/helpers';`,
},
{
code: `import { foo } from 'some-other-module';`,
},
],
invalid: [
{
code: `import percySnapshot from '@percy/ember';`,
errors: [{ messageId: 'noPercyDirectImport' }],
output: `import { percySnapshot } from '@cardstack/host/tests/helpers';`,
},
{
code: `import { percySnapshot } from '@percy/ember';`,
errors: [{ messageId: 'noPercyDirectImport' }],
output: `import { percySnapshot } from '@cardstack/host/tests/helpers';`,
},
],
});
1 change: 1 addition & 0 deletions packages/host/tests/helpers/percy-snapshot.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { pauseTest, settled } from '@ember/test-helpers';

// eslint-disable-next-line @cardstack/boxel/no-percy-direct-import
import originalPercySnapshot from '@percy/ember';

import QUnit from 'qunit';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
import { tracked } from '@glimmer/tracking';

import Plane from '@cardstack/boxel-icons/plane';
import percySnapshot from '@percy/ember';
import { getService } from '@universal-ember/test-support';
import format from 'date-fns/format';
import parseISO from 'date-fns/parseISO';
Expand Down Expand Up @@ -47,6 +46,7 @@ import {
testRealmURL,
setupCardLogs,
saveCard,
percySnapshot,
provideConsumeContext,
testModuleRealm,
setupIntegrationTestRealm,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { waitUntil } from '@ember/test-helpers';
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';

import percySnapshot from '@percy/ember';
import { getService } from '@universal-ember/test-support';
import { module, test } from 'qunit';

Expand Down Expand Up @@ -220,8 +219,6 @@ ${REPLACE_MARKER}
assert.dom('.cdr.line-delete').exists({ count: 2 });
assert.dom('.cdr.line-insert').exists({ count: 1 });
assert.dom('[data-test-apply-code-button]').exists();

await percySnapshot(assert);
});

test('it will render one diff editor and one standard code block if one search replace block is complete and another is not', async function (assert) {
Expand Down Expand Up @@ -318,8 +315,6 @@ let c = 3;
lines?.innerText === '// existing code ... \nlet a = 1;\nlet c = 3;'
);
});

await percySnapshot(assert);
});

test('unincremental updates are handled gracefully', async function (assert) {
Expand Down