Create a project
For simplicity, we'll assume our target project to be an Ember app. That is, the relevant files live in the app folder.
Use the CLI
Change the directory to a place where you like to keep projects. Then, run these commands:
sh
# Create project
pnpx @codemod-utils/cli remove-test-selectors --addon ast-template ast-template-tag
# Install dependencies
cd remove-test-selectors
pnpm installScaffold step
Create a step called remove-test-selectors. It is to read *.{gjs,gts,hbs} files and write back the file content (a no-op).
Solution
For brevity, how src/index.ts calls removeTestSelectors is not shown.
ts
import { readFileSync } from 'node:fs';
import { join } from 'node:path';
import { createFiles, findFiles } from '@codemod-utils/files';
import type { Options } from '../types/index.js';
function removeDataTestAttributes(file: string): string {
return file;
}
export function removeTestSelectors(options: Options): void {
const { projectRoot } = options;
const filePaths = findFiles('app/**/*.{gjs,gts,hbs}', {
projectRoot,
});
const fileMap = new Map(
filePaths.map((filePath) => {
let file = readFileSync(join(projectRoot, filePath), 'utf8');
file = removeDataTestAttributes(file);
return [filePath, file];
}),
);
createFiles(fileMap, options);
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
To test this step, we create a component with three <template> tags and the index route to render the component.
gjs
import { on } from '@ember/modifier';
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import styles from './my-component.css';
const Control =
<template>
<div class={{styles.control}}>
<button
data-test-button="Increment"
type="button"
{{on "click" @onClick}}
>
Increment by 1
</button>
</div>
</template>
const Display =
<template>
<div class={{styles.display}}>
Count:
<p class={{styles.count}} data-test-count ...attributes>
{{@count}}
</p>
</div>
</template>
export default class MyComponent extends Component {
@tracked count = 0;
increment = () => {
this.count++;
}
<template>
<div class={{styles.container}}>
<Control
@onClick={{this.increment}}
/>
<Display @count={{this.count}} data-test-my-count />
</div>
</template>
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
hbs
<div data-test-my-component>
<MyComponent />
</div>1
2
3
2
3
NOTE
One file tests the *.{gjs,gts} case, while the other *.hbs.
Indentations are inconsistent on purpose. We'll check whether formatting is preserved.