@jsenv/navi 0.29.155 → 0.29.156
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/jsenv_navi.js +32 -2
- package/dist/jsenv_navi.js.map +6 -5
- package/docs/testid.md +47 -1
- package/package.json +1 -1
package/docs/testid.md
CHANGED
|
@@ -78,6 +78,27 @@ than to the box around it (`id`, `name`, `type`, `value`, `tabIndex`,
|
|
|
78
78
|
so a `data-test-id` or a `data-qa` of your own would name the wrapper, which is
|
|
79
79
|
the second reason to keep the standard spelling.
|
|
80
80
|
|
|
81
|
+
`aria-label` and `aria-labelledby` take the same road, and for the reason the
|
|
82
|
+
section above gives: the name has to be where the role is. The root box has no
|
|
83
|
+
role — it is a wrapper — so a name left on it would be announced by nothing and
|
|
84
|
+
found by nothing, while the host is what the user focuses and what
|
|
85
|
+
`getByRole(role, { name })` and `getByLabel()` read.
|
|
86
|
+
|
|
87
|
+
```jsx
|
|
88
|
+
<Picker variant="icon" aria-label="Aide" ui={<Icon>…</Icon>} />
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
```html
|
|
92
|
+
<div class="navi_picker" navi-control="picker" aria-expanded="false">
|
|
93
|
+
<input navi-control-host="picker" aria-label="Aide" readonly />
|
|
94
|
+
</div>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Which role that host answers to is the control's own: a picker's host is an
|
|
98
|
+
`<input>` (`textbox`), a button's is a `<button>`. A picker trigger is not
|
|
99
|
+
`getByRole("button")`, whatever it is drawn like — target its name, or give it
|
|
100
|
+
a `data-testid`.
|
|
101
|
+
|
|
81
102
|
When the wrapper IS what the test wants — a whole field with its label and its
|
|
82
103
|
error message, a section, a row — put the testid on the surrounding component
|
|
83
104
|
(`<Field data-testid="email-field">`, `<Box data-testid="cart-row">`); anything
|
|
@@ -97,7 +118,32 @@ Most tests do not need it — a testid on what the popup holds (`<Box
|
|
|
97
118
|
data-testid="place-pick">` among the children) names the screen, not the frame,
|
|
98
119
|
and is the better name for a test that reads or clicks the content. Reach for
|
|
99
120
|
`popupTestId` when the frame IS what the test looks at: a screenshot of the
|
|
100
|
-
popup's surface, its position, its size, its backdrop.
|
|
121
|
+
popup's surface, its position, its size, its backdrop. It names the popup in
|
|
122
|
+
every mode, including `mode="callout"`, where the frame is a callout rather
|
|
123
|
+
than a sheet.
|
|
124
|
+
|
|
125
|
+
## A callout is a role first
|
|
126
|
+
|
|
127
|
+
A callout — a control's `readOnlyMessage` or failing constraint, a
|
|
128
|
+
`mode="callout"` picker, a direct `openCallout()` — is drawn by navi from end to
|
|
129
|
+
end: the application supplies the sentence and nothing else, so there is often
|
|
130
|
+
nothing of its own to name. It carries a role for that, and the role is the
|
|
131
|
+
contract: `alert` when it says something went wrong (`warning`, `error`),
|
|
132
|
+
`status` otherwise (`info`, `success`, or no status at all).
|
|
133
|
+
|
|
134
|
+
```js
|
|
135
|
+
await page.getByRole("button", { name: "Publier" }).click();
|
|
136
|
+
await expect(page.getByRole("alert")).toHaveText("Il manque le lieu");
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
That is not a testing convenience: a message appearing without the user asking
|
|
140
|
+
for it is what a live region is for, and the role is what makes a screen reader
|
|
141
|
+
read it out. A test targeting it asserts that.
|
|
142
|
+
|
|
143
|
+
When the role is not enough — two callouts up at once, a screenshot of one
|
|
144
|
+
particular surface — `openCallout` takes a `testId`, and a picker's
|
|
145
|
+
`popupTestId` covers the one it opens. Waiting on `.navi_callout` is the thing
|
|
146
|
+
to replace: it is a navi class like any other.
|
|
101
147
|
|
|
102
148
|
`<ControlSwap.Side>` answers the same situation the other way: the cap at the
|
|
103
149
|
end of the row is drawn by navi, and every prop the side does not use for
|