feat(Example): add checkmark script for tests#4087
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a release utility script intended to generate a Markdown checklist/table of test scenarios by discovering scenario-description.ts files under the app tests directory and grouping them into Smoke vs Non-Smoke sections.
Changes:
- Introduces
scripts/release/generate-test-checklist.tsto crawl the tests tree and collect scenario metadata. - Adds Markdown table generation with configurable columns and sorting/grouping logic.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| async function parseScenarioFile( | ||
| filePath: string, | ||
| ): Promise<ScenarioDescription | null> { | ||
| try { | ||
| const module = require(filePath); | ||
| return module[OBJECT_NAME]; | ||
| } catch (e) { | ||
| console.error( | ||
| `Warning: could not import ${filePath}: ${(e as Error).message}`, |
There was a problem hiding this comment.
This is something I recall you told me last week. Don't we need the scenario-description files to migrate to non-default exports first?
There was a problem hiding this comment.
Yes, the change regarding exports is already merged to main branch. I've just rebased so it's all good
| const fs = require('fs'); | ||
| const path = require('path'); | ||
| import type { ScenarioDescription } from '../../apps/src/tests/shared/helpers.ts'; | ||
|
|
||
| type E2eCoverage = ScenarioDescription['e2eCoverage']; | ||
|
|
There was a problem hiding this comment.
Inaccurate. Newer node versions (which we use) run TS directly.
Only thing I'm concerned here is that indeed, we mix require style imports for modules with import directives for types. This looks weird, however I dunno whether we can workaround this one. Please do 10-min of research here.
There was a problem hiding this comment.
Mixing require with import is generally incorrect, but in this case it is admissible as we only use import for a type (which does not exist in runtime). However, if we switch to "type": "module" in the future, we should change all require calls to import.
| @@ -0,0 +1,166 @@ | |||
| const fs = require('fs'); | |||
| const path = require('path'); | |||
| import type { ScenarioDescription } from '../../apps/src/tests/shared/helpers.ts'; | |||
There was a problem hiding this comment.
Bot is right here.
Additionally, its smelly to import things across modules like this, but I guess it'll do for now. Otherwise we'd have to duplicate the ScenarioDescription definition which is not great either.
The proper solution here would be to move these symbols to some third, shared module. This will be doable easily after we migrate to monorepo setup.
Let's create ticket for the above and link it here, please ☝🏻
There was a problem hiding this comment.
Bot is right here.
Additionally, its smelly to import things across modules like this, but I guess it'll do for now. Otherwise we'd have to duplicate the ScenarioDescription definition which is not great either.
The proper solution here would be to move these symbols to some third, shared module. This will be doable easily after we migrate to monorepo setup.
Let's create ticket for the above and link it here, please ☝🏻
There was a problem hiding this comment.
Ticket: https://github.com/software-mansion/react-native-screens-labs/issues/1492
Commit regarding import: b303bdb
| function compareEntries(a: Entry, b: Entry): number { | ||
| const coverageDiff = | ||
| COVERAGE_ORDER[a.e2eCoverage] - COVERAGE_ORDER[b.e2eCoverage]; | ||
| if (coverageDiff !== 0) { | ||
| return coverageDiff; | ||
| } | ||
|
|
||
| if (a.subdirectory !== b.subdirectory) { | ||
| return a.subdirectory.localeCompare(b.subdirectory); | ||
| } | ||
|
|
||
| return a.name.localeCompare(b.name); | ||
| } |
There was a problem hiding this comment.
I think +1 here. We should sort by key instead of name.
| const cellValue = (col: TableColumn, entry: Entry) => | ||
| col.prop | ||
| ? String(entry[col.prop as keyof Entry] ?? 'N/A') | ||
| : col.defaultValue!; | ||
|
|
716b6dd to
2f40512
Compare
kkafar
left a comment
There was a problem hiding this comment.
Hey! This looks good. Good job.
I have few remarks. Please answer them before proceeding.
| @@ -0,0 +1,166 @@ | |||
| const fs = require('fs'); | |||
| const path = require('path'); | |||
| import type { ScenarioDescription } from '../../apps/src/tests/shared/helpers.ts'; | |||
There was a problem hiding this comment.
Bot is right here.
Additionally, its smelly to import things across modules like this, but I guess it'll do for now. Otherwise we'd have to duplicate the ScenarioDescription definition which is not great either.
The proper solution here would be to move these symbols to some third, shared module. This will be doable easily after we migrate to monorepo setup.
Let's create ticket for the above and link it here, please ☝🏻
| @@ -0,0 +1,166 @@ | |||
| const fs = require('fs'); | |||
| const path = require('path'); | |||
| import type { ScenarioDescription } from '../../apps/src/tests/shared/helpers.ts'; | |||
There was a problem hiding this comment.
Bot is right here.
Additionally, its smelly to import things across modules like this, but I guess it'll do for now. Otherwise we'd have to duplicate the ScenarioDescription definition which is not great either.
The proper solution here would be to move these symbols to some third, shared module. This will be doable easily after we migrate to monorepo setup.
Let's create ticket for the above and link it here, please ☝🏻
| const fs = require('fs'); | ||
| const path = require('path'); | ||
| import type { ScenarioDescription } from '../../apps/src/tests/shared/helpers.ts'; | ||
|
|
||
| type E2eCoverage = ScenarioDescription['e2eCoverage']; | ||
|
|
There was a problem hiding this comment.
Inaccurate. Newer node versions (which we use) run TS directly.
Only thing I'm concerned here is that indeed, we mix require style imports for modules with import directives for types. This looks weird, however I dunno whether we can workaround this one. Please do 10-min of research here.
| async function parseScenarioFile( | ||
| filePath: string, | ||
| ): Promise<ScenarioDescription | null> { | ||
| try { | ||
| const module = require(filePath); | ||
| return module[OBJECT_NAME]; | ||
| } catch (e) { | ||
| console.error( | ||
| `Warning: could not import ${filePath}: ${(e as Error).message}`, |
There was a problem hiding this comment.
This is something I recall you told me last week. Don't we need the scenario-description files to migrate to non-default exports first?
| function compareEntries(a: Entry, b: Entry): number { | ||
| const coverageDiff = | ||
| COVERAGE_ORDER[a.e2eCoverage] - COVERAGE_ORDER[b.e2eCoverage]; | ||
| if (coverageDiff !== 0) { | ||
| return coverageDiff; | ||
| } | ||
|
|
||
| if (a.subdirectory !== b.subdirectory) { | ||
| return a.subdirectory.localeCompare(b.subdirectory); | ||
| } | ||
|
|
||
| return a.name.localeCompare(b.name); | ||
| } |
There was a problem hiding this comment.
I think +1 here. We should sort by key instead of name.
There was a problem hiding this comment.
Looks good, thank you!
Just FYI, markdown does not support checkboxes within tables. Therefore, if we wish to mark an item in this table, we will need to manually enter an "x" inside [ ], as opposed to clicking a checkbox (as it works in the PR checklist). I will create a task to update the test release scope with information regarding this limitation and the script usage.
## Description Adding `tsconfig.json` and `.eslintrc.js` to `scripts` directory is necessary in order for the new script, introduced in #4087, to work properly. ## Changes - add `tsconfig.json` and `.eslintrc.js` to `scripts` directory ## Before & after - visual documentation N/A ## Test plan N/A ## Checklist - [ ] Included code example that can be used to test this change. - [ ] For visual changes, included screenshots / GIFs / recordings documenting the change. - [ ] For API changes, updated relevant public types. - [ ] Ensured that CI passes --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
| async function parseScenarioFile( | ||
| filePath: string, | ||
| ): Promise<ScenarioDescription | null> { | ||
| try { | ||
| const module = require(filePath); | ||
| return module[OBJECT_NAME]; |
There was a problem hiding this comment.
According to TS documentation:
.ts/.tsx/.js/.jsx/.d.ts files are ES modules if the nearest ancestor package.json file contains "type": "module", otherwise CommonJS modules
So using require(filePath) is correct
| if (a.key !== b.subdirectory) { | ||
| return a.subdirectory.localeCompare(b.subdirectory); | ||
| } | ||
|
|
||
| return a.key.localeCompare(b.key); |
| @@ -0,0 +1,164 @@ | |||
| const fs = require('fs'); | |||
| const path = require('path'); | |||
| import type { ScenarioDescription } from '../../apps/src/tests/shared/helpers.ts'; | |||
| const customTestPath = getCustomTestPath(); | ||
| const searchDir = customTestPath | ||
| ? path.resolve(process.cwd(), customTestPath) | ||
| : path.resolve(__dirname, DEFAULT_TESTS_DIR); |
ff37bf3 to
b303bdb
Compare
kkafar
left a comment
There was a problem hiding this comment.
Okay, just tested it and seems to work fine, both with default settings and when specifying the --test-path option.
Since the code here is rather hard to follow, one more thing we're missing is a comment in the very top of the file, describing what this script does and documenting input it receives (--test-path parameter). Otherwise nobody is going to be able to decipher that even such option exists.
Added in 650b895 |
Description
This PR adds a new utility script that automatically collects information about test scenarios and generates readable Markdown tables based on their metadata.
The script processes the collected data and outputs it into two separate sections: Smoke Tests and Non-Smoke Tests. Currently, the generated tables include the following columns:
Mark(rendered as an empty checkbox [ ]),Test Name,E2E CoverageandKey. The entries in both tables are sorted first by E2E coverage priority, and then alphabetically by their file path. This ensures that tests related to the same features or areas are grouped logically together in the list.If you want to add a new property or column to the table in the future, you simply need to add a new object to the
TABLE_COLUMNSarray inside the script.To execute the script, simply run it using Node.js:
node path-to/generate-test-checklist.tsBy default, the script searches the standard test directory, but you can override this behavior by passing a custom path using the
--test-path <path>flag.Note
Adding
tsconfig.jsonand.eslintrc.jsfiles toscriptsdirectory will be handled in a separate PR.Changes
generate-test-checklist.tsinscripts/releasedirectoryVisual documentation
That's how tables are meant to look like:
Test plan
N/A
Checklist