diff --git a/.vscode/settings.json b/.vscode/settings.json index 1328677..290317a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,24 +1,23 @@ { "cSpell.words": [ "beus", + "brc", + "brcc", + "brh", + "brhl", + "bro", + "bron", + "bteew", + "btesw", + "btew", + "btf", + "bti", + "bts", + "btsi", + "btsw", "deinsoftware", "Equiman", - "gabr", - "gabro", - "gbrc", - "gbrcc", - "gbrh", - "gbrhl", - "gbro", - "gbteew", - "gbtesw", - "gbtew", - "gbtf", - "gbti", - "gbts", - "gbtsi", - "gbtsw", - "github", + "ithub", "itrh", "itue", "matc", @@ -26,6 +25,8 @@ "rewi", "rswi", "sltp", + "SWPM", + "testid", "volta" ], "markdownlint.config": { diff --git a/CHANGELOG.md b/CHANGELOG.md index eecef9e..6e356ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,17 @@ Fixed for any bug fixes. Security to invite users to upgrade in case of vulnerabilities. --> +## 0.0.6 - 2023/04/17 + +### Added + +- cheat sheet helper section on README +- wait for snippets + +### Changed + +- snippets with multiple search variants to avoid repetition + ## 0.0.5 - 2023/04/16 ### Added diff --git a/README.md b/README.md index 0ac61f7..b1da5e0 100644 --- a/README.md +++ b/README.md @@ -19,11 +19,13 @@ The quick and easy way to create and use Testing Library with [VS Code](https:// - [Extension Manager](#extension-manager) - [Marketplace](#marketplace) - [Supported Languages](#supported-languages) +- [Cheat Sheet](#cheat-sheet) - [Snippets](#snippets) - [Import](#import) - [User Event](#user-event) - [Queries](#queries) - [Regex](#regex) + - [Wait](#wait) - [Keyboard](#keyboard) - [Settings](#settings) - [About](#about) @@ -68,6 +70,32 @@ Open the extension manager with ctrl+shift+X (W --- +## Cheat Sheet + +| Search Variants | Result | +| ---------------- | --------------------------------------------- | +| `getBy`... | `Element` or `Error` | +| `getAllBy`... | `Element[]` or `Error` | +| `queryBy`... | `Element` or `null` | +| `queryAllBy`... | `Element[]` or `null` | +| `findBy`... | `Promise` or `Promise` | +| `findAllBy`... | `Promise` or `Promise` | + +| Search Types | Result | +| --------------------- | --------------------------------------------- | +| ...`Role` | `` or [Aria Roles](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques#roles) | +| ...`LabelText` | `` | +| ...`PlaceHolderText` | `` | +| ...`Text` | `Text` | +| ...`DisplayValue` | `` | +| ...`AltText` | `` | +| ...`Title` | `` or `` | +| ...`TestId` | `` | + +⇧ [Back to menu](#menu) + +--- + ## Snippets Below is a list of all available snippets and the triggers of each one. The `░` means the `TAB` jump position and `█` the final cursor position. @@ -90,48 +118,63 @@ Below is a list of all available snippets and the triggers of each one. The `░ ### Queries -| Trigger | Result | -| --------: | ---------------------------------------------------------------- | -| `gbr→` | `screen.getByRole('░id')█` | -| `gbro→` | `screen.getByRole('░id', {░})█` | -| `gbrc→` | `screen.getByRole('checkbox')█` | -| `gbrcc→` | `screen.getByRole('checkbox', { checked: ░} })█` | -| `gbrh→` | `screen.getByRole('heading')█` | -| `gbrhl→` | `screen.getByRole('heading', { level: ░<1\|2\|3\|4\|5\|6>} })█` | -| `gabr→` | `screen.getAllByRole('░id')█` | -| `gabro→` | `screen.getAllByRole('░id', {░})█` | -| `gbt→` | `screen.getByText(░)█` | -| `gbtf→` | `screen.getByText('░Text Match')█` | -| `gbti→` | `screen.getByText('░text match', {ignore: false})█` | -| `gbts→` | `screen.getByText('░ext Matc', {exact: false})█` | -| `gbtsi→` | `screen.getByText('░ext matc', {exact: false, ignore: false})█` | -| `gbtsw→` | `screen.getByText((content) => content.startsWith('░Text'))█` | -| `gbtesw→` | screen.getByText((content, element) => { return element.tagName.toLowerCase() === '░div' && content.startsWith('░Text')})█ | -| `gbtew→` | `screen.getByText((content) => content.endsWith('░Match'))█` | -| `gbteew→` | screen.getByText((content, element) => { return element.tagName.toLowerCase() === '░div' && content.endsWith('░Match')})█ | +Sorted by recommended official priority + +1. Role + +| Trigger | Result | +| :------- | ----------------------------------------------------------------- | +| `br→` | `screen.░getByRole('░id')█` | +| `bro→` | `screen.░getByRole('░id', {░})█` | +| `bron→` | `screen.░getByRole('░id', {name: ░})█` | +| `brc→` | `screen.░getByRole('checkbox')█` | +| `brcc→` | `screen.░getByRole('checkbox', { checked: ░} })█` | +| `brh→` | `screen.░getByRole('heading')█` | +| `brhl→` | `screen.░getByRole('heading', { level: ░<1\|2\|3\|4\|5\|6>} })█` | + +4. Text + +| Trigger | Result | +| :------- | ---------------------------------------------------------------- | +| `bt→` | `screen.░getByText(░)█` | +| `btf→` | `screen.░getByText('░Text Match')█` | +| `bti→` | `screen.░getByText('░text match', {ignore: false})█` | +| `bts→` | `screen.░getByText('░ext Matc', {exact: false})█` | +| `btsi→` | `screen.░getByText('░ext matc', {exact: false, ignore: false})█` | +| `btsw→` | `screen.░getByText((content) => content.startsWith('░Text'))█` | +| `btesw→` | screen.░getByText((content, element) => { return element.tagName.toLowerCase() === '░div' && content.startsWith('░Text')})█ | +| `btew→` | `screen.░getByText((content) => content.endsWith('░Match'))█` | +| `bteew→` | screen.░getByText((content, element) => { return element.tagName.toLowerCase() === '░div' && content.endsWith('░Match')})█ | ### Debug | Trigger | Result | -| -------: | ------------------------------------ | -| `sd→` | `screen.debug()█` | -| `sltp→` | `screen.logTestingPlaygroundURL()█` | +| :------- | ------------------------------------ | +| `sd→` | `screen.debug()█` | +| `sltp→` | `screen.logTestingPlaygroundURL()█` | ### Regex It can be used as a text matcher or `name` property on queries. | Trigger | Description | Result | -| ------: | --------------------------- | ------------------- | -| `rf→` | full text match | `/^░Text Match$/█` | -| `rfi→` | full text match ignore case | `/^░text match$/i█` | -| `rs→` | substring match | `/░ext Matc/█` | -| `rsi→` | substring match ignore case | `/░ext matc/i█` | -| `rsw→` | start with | `/^░Text/█` | +| :------ | --------------------------- | ------------------- | +| `rf→` | full text match | `/^░Text Match$/█` | +| `rfi→` | full text match ignore case | `/^░text match$/i█` | +| `rs→` | substring match | `/░ext Matc/█` | +| `rsi→` | substring match ignore case | `/░ext matc/i█` | +| `rsw→` | start with | `/^░Text/█` | | `rswi→` | start with ignore case | `/^░text/i█` | -| `rew→` | end with | `/░Match$/█` | +| `rew→` | end with | `/░Match$/█` | | `rewi→` | end with ignore case | `/░match$/i█` | +### Wait + +| Trigger | Result | +| :------- | ------------------------------------------------------------------------------- | +| `wf→` | await waitFor( () => ░)█ | +| `wfr→` | await waitForElementToBeRemoved( () => ░)█ | + ⇧ [Back to menu](#menu) --- diff --git a/package.json b/package.json index 6f99202..380c126 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "testing-library-snippets", "description": "VS Code Testing Library snippets for JS and TS", - "version": "0.0.5", + "version": "0.0.6", "displayName": "Testing Library Snippets", "publisher": "deinsoftware", "icon": "images/light-icon.png", diff --git a/snippets/queries.json b/snippets/queries.json index 5c7fe6d..f7a057b 100644 --- a/snippets/queries.json +++ b/snippets/queries.json @@ -1,100 +1,119 @@ { - "getBy.role": { - "prefix": "gbr", - "body": ["screen.getByRole('${1:id}')$0"], - "description": "getByRole query" - }, - "getBy.role.options": { - "prefix": "gbro", - "body": ["screen.getByRole('${1:id}', {$2})$0"], - "description": "getByRole query with options" + "by.role": { + "prefix": "br", + "body": [ + "screen.${1|getBy,getAllBy,queryBy,queryAllBy,findBy,findByAll|}Role('${2:id}')$0" + ], + "description": "Role query" }, - "getBy.role.checkbox": { - "prefix": "gbrc", - "body": ["screen.getByRole('checkbox')$0"], - "description": "getByRole checkbox" + "by.role.options": { + "prefix": "bro", + "body": [ + "screen.${1|getBy,getAllBy,queryBy,queryAllBy,findBy,findByAll|}Role('${2:id}', {$3})$0" + ], + "description": "Role query with options" }, - "getBy.role.checkbox.checked": { - "prefix": "gbrcc", - "body": ["screen.getByRole('checkbox', { checked: ${1|true,false|} })$0"], - "description": "getByRole checkbox checked" + "by.role.options.name": { + "prefix": "bron", + "body": [ + "screen.${1|getBy,getAllBy,queryBy,queryAllBy,findBy,findByAll|}Role('${2:id}',\t{$3})$0" + ], + "description": "Role query with name on options" }, - "getBy.role.heading": { - "prefix": "gbrh", - "body": ["screen.getByRole('heading')$0"], - "description": "getByRole heading" + "by.role.checkbox": { + "prefix": "brc", + "body": [ + "screen.${1|getBy,getAllBy,queryBy,queryAllBy,findBy,findByAll|}Role('checkbox')$0" + ], + "description": "Role checkbox" }, - "getBy.role.heading.level": { - "prefix": "gbrhl", - "body": ["screen.getByRole('heading', { level: ${1|1,2,3,4,5,6|} })$0"], - "description": "getByRole heading level" + "by.role.checkbox.checked": { + "prefix": "brcc", + "body": [ + "screen.${1|getBy,getAllBy,queryBy,queryAllBy,findBy,findByAll|}Role('checkbox', { checked: ${2|true,false|} })$0" + ], + "description": "Role checkbox checked" }, - "getAllBy.role": { - "prefix": "gabr", - "body": ["screen.getAllByRole('${1:id}')$0"], - "description": "getAllByRole query" + "by.role.heading": { + "prefix": "brh", + "body": [ + "screen.${1|getBy,getAllBy,queryBy,queryAllBy,findBy,findByAll|}Role('heading')$0" + ], + "description": "Role heading" }, - "getAllBy.role.options": { - "prefix": "gabro", - "body": ["screen.getAllByRole('${1:id}', {$2})$0"], - "description": "getAllByRole query with options" + "by.role.heading.level": { + "prefix": "brhl", + "body": [ + "screen.${1|getBy,getAllBy,queryBy,queryAllBy,findBy,findByAll|}Role('heading', { level: ${2|1,2,3,4,5,6|} })$0" + ], + "description": "Role heading level" }, - "getBy.text": { - "prefix": "gbt", - "body": ["screen.getByText($1)$0"], - "description": "getByText query" + "by.text": { + "prefix": "bt", + "body": [ + "screen.${1|getBy,getAllBy,queryBy,queryAllBy,findBy,findByAll|}Text($2)$0" + ], + "description": "Text query" }, - "getBy.text.full": { - "prefix": "gbtf", - "body": ["screen.getByText('${1:Text Match}')$0"], - "description": "getByText query full string match" + "by.text.full": { + "prefix": "btf", + "body": [ + "screen.${1|getBy,getAllBy,queryBy,queryAllBy,findBy,findByAll|}Text('${2:Text Match}')$0" + ], + "description": "Text query full string match" }, - "getBy.text.ignore": { - "prefix": "gbti", - "body": ["screen.getByText('${1:text match}', {ignore: false})$0"], - "description": "getByText query full string ignore case" + "by.text.ignore": { + "prefix": "bti", + "body": [ + "screen.${1|getBy,getAllBy,queryBy,queryAllBy,findBy,findByAll|}Text('${2:text match}', {ignore: false})$0" + ], + "description": "Text query full string ignore case" }, - "getBy.text.substring": { - "prefix": "gbts", - "body": ["screen.getByText('${1:ext Matc}', {exact: false})$0"], - "description": "getByText query substring match" + "by.text.substring": { + "prefix": "bts", + "body": [ + "screen.${1|getBy,getAllBy,queryBy,queryAllBy,findBy,findByAll|}Text('${2:ext Matc}', {exact: false})$0" + ], + "description": "Text query substring match" }, - "getBy.text.substring+ignore": { - "prefix": "gbtsi", + "by.text.substring+ignore": { + "prefix": "btsi", "body": [ - "screen.getByText('${1:ext matc}', {exact: false, ignore: false})$0" + "screen.${1|getBy,getAllBy,queryBy,queryAllBy,findBy,findByAll|}Text('${2:ext matc}', {exact: false, ignore: false})$0" ], - "description": "getByText query substring match ignore case" + "description": "Text query substring match ignore case" }, - "getBy.text.startWith": { - "prefix": "gbtsw", + "by.text.startWith": { + "prefix": "btsw", "body": [ - "screen.getByText((content) => content.startsWith('${1:Text}'))$0" + "screen.${1|getBy,getAllBy,queryBy,queryAllBy,findBy,findByAll|}Text((content) => content.startsWith('${2:Text}'))$0" ], - "description": "getByText query start with match" + "description": "Text query start with match" }, - "getBy.text.element.startWith": { - "prefix": "gbtesw", + "by.text.element.startWith": { + "prefix": "btesw", "body": [ - "screen.getByText((content, element) => {", - "\treturn element.tagName.toLowerCase() === '${1:div}' && content.startsWith('${2:Text}')", + "screen.${1|getBy,getAllBy,queryBy,queryAllBy,findBy,findByAll|}Text((content, element) => {", + "\treturn element.tagName.toLowerCase() === '${2:div}' && content.startsWith('${3:Text}')", "})" ], - "description": "getByText query start with match on specific element" + "description": "Text query start with match on specific element" }, - "getBy.text.endWith": { - "prefix": "gbtew", - "body": ["screen.getByText((content) => content.endsWith('${1:Match}'))$0"], - "description": "getByText query end with match" + "by.text.endWith": { + "prefix": "btew", + "body": [ + "screen.${1|getBy,getAllBy,queryBy,queryAllBy,findBy,findByAll|}Text((content) => content.endsWith('${2:Match}'))$0" + ], + "description": "Text query end with match" }, - "getBy.text.element.endWith": { - "prefix": "gbteew", + "by.text.element.endWith": { + "prefix": "bteew", "body": [ - "screen.getByText((content, element) => {", - "\treturn element.tagName.toLowerCase() === '${1:div}' && content.endsWith('${1:Match}')", + "screen.${1|getBy,getAllBy,queryBy,queryAllBy,findBy,findByAll|}Text((content, element) => {", + "\treturn element.tagName.toLowerCase() === '${2:div}' && content.endsWith('${3:Match}')", "})" ], - "description": "getByText query end with match on specific element" + "description": "Text query end with match on specific element" } } diff --git a/snippets/wait.json b/snippets/wait.json new file mode 100644 index 0000000..2476fd9 --- /dev/null +++ b/snippets/wait.json @@ -0,0 +1,12 @@ +{ + "wait.for": { + "prefix": "wf", + "body": ["await waitFor(", "\t() => $1", ")$0"], + "description": "wait for" + }, + "wait.for.removed": { + "prefix": "wfr", + "body": ["await waitForElementToBeRemoved(", "\t() => $1", ")$0"], + "description": "wait for element to be removed" + } +}
screen.getByText((content, element) => { return element.tagName.toLowerCase() === '░div' && content.startsWith('░Text')})█
screen.getByText((content, element) => { return element.tagName.toLowerCase() === '░div' && content.endsWith('░Match')})█
screen.░getByText((content, element) => { return element.tagName.toLowerCase() === '░div' && content.startsWith('░Text')})█
screen.░getByText((content, element) => { return element.tagName.toLowerCase() === '░div' && content.endsWith('░Match')})█
await waitFor( () => ░)█
await waitForElementToBeRemoved( () => ░)█