@rnw-community/wdio 0.49.2 → 0.50.0

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.
Files changed (2) hide show
  1. package/package.json +3 -3
  2. package/readme.md +280 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rnw-community/wdio",
3
- "version": "0.49.2",
3
+ "version": "0.50.0",
4
4
  "description": "WDIO commands, page objects and utils",
5
5
  "keywords": [
6
6
  "wdio",
@@ -43,9 +43,9 @@
43
43
  "engines": {
44
44
  "node": ">=14.0.0"
45
45
  },
46
- "gitHead": "61aea17066649651f3867b0021d2ab2ccd1f3105",
46
+ "gitHead": "f5d105c1a22590f3ba6e3e2cd6a56a3f2c0f2eb9",
47
47
  "devDependencies": {
48
- "@rnw-community/shared": "^0.49.0",
48
+ "@rnw-community/shared": "^0.50.0",
49
49
  "@wdio/globals": "^8.5.1",
50
50
  "@wdio/protocols": "^8.3.11",
51
51
  "expect-type": "^0.13.0",
package/readme.md CHANGED
@@ -32,7 +32,7 @@ import { Text } from 'react-native';
32
32
 
33
33
  import { IOSTestIDProps, setTestId } from '@rnw-community/wdio';
34
34
 
35
- export const DynamicComponent: FC<IOSTestIDProps> = ({ testID = 'ParentTestID' }) => (
35
+ export const DynamicComponent: = ({ testID = 'ParentTestID' }:IOSTestIDProps) => (
36
36
  <Text {...setTestId(testID, `Text`)}>Text</Text>
37
37
  );
38
38
  ```
@@ -42,3 +42,282 @@ Which will generate `ParentTestID_Text`;
42
42
  ### getTestID
43
43
 
44
44
  ### setPropTestID
45
+
46
+ Setting _testID_ similar to `setTestID` but with overriding default _testID_.
47
+
48
+ ```tsx
49
+ import React from 'react';
50
+ import { Text } from 'react-native';
51
+ import { TestIDProps } from '@rnw-community/wdio';
52
+
53
+ interface Props extends TestIDProps, React.PropsWithChildren {
54
+ testID?: string;
55
+ }
56
+
57
+ const defaultTestID = 'DynamicComponent.Root';
58
+
59
+ export const DynamicComponent = ({children, ...props}:Props) => (
60
+ <View {...setPropTestID(defaultTestID, props)}>
61
+ {children}
62
+ </View>);
63
+ ```
64
+
65
+ ## Commands
66
+
67
+ ### Setup
68
+ #### copy 2 d.ts files into root of your e2e project
69
+
70
+ * [wdio.d.ts](https://github.com/rnw-community/rnw-community/blob/9294a867193951b8f37310ef0f7092c74f6b87f2/packages/wdio/src/wdio.d.ts)
71
+ * [webdriverio.d.ts](https://github.com/rnw-community/rnw-community/blob/9294a867193951b8f37310ef0f7092c74f6b87f2/packages/wdio/src/wevdriverio.d.ts)
72
+
73
+ #### add wdio.config.js to your e2e project
74
+
75
+ ```ts
76
+ import { addWdioCommands } from '@rnw-community/wdio';
77
+
78
+ export const wdioBaseConfiguration = (): WebdriverIO.Config => ({
79
+ //...your config
80
+ before(_capabilities, _specs, browser: WebdriverIO.Browser) {
81
+ addWdioCommands(browser);
82
+ },
83
+ });
84
+
85
+ ```
86
+ ### Usage
87
+
88
+ #### openDeepLink
89
+
90
+ No more manually open safary, locate address and enter link with unicode enter in the end
91
+
92
+ ```ts
93
+ import driver from '@wdio/globals';
94
+
95
+ describe('DeepLink', () => {
96
+ it('should open deep link', async () => {
97
+ await driver.openDeepLink('myapp://products/1234');
98
+ });
99
+ });
100
+ ```
101
+
102
+ #### testID$ and testID$$
103
+
104
+ `testID$` and `testID$$` are the same as `$` and `$$` but with support for testID selector
105
+
106
+ ```ts
107
+ import driver from '@wdio/globals';
108
+
109
+ describe('DynamicComponent', () => {
110
+ it('should find component', async () => {
111
+ await expect(driver.testID$('DynamicComponent.Root')).toBeDisplayed();
112
+ });
113
+ });
114
+ ```
115
+
116
+ #### testID$$Index
117
+
118
+ `testID$$Index` is the same as `$$` but with support for testID selector and index. Returns element by index
119
+
120
+ ```ts
121
+ import driver from '@wdio/globals';
122
+
123
+ describe('DynamicComponent', () => {
124
+ it('should find root element', async () => {
125
+ await expect(driver.testID$$Index('DynamicComponent.Root', 0)).toBeDisplayed();
126
+ });
127
+ });
128
+ ```
129
+ #### slowInput
130
+
131
+ `slowInput` is the same as `setValue` but with support for typing speed
132
+
133
+ ```ts
134
+ import driver from '@wdio/globals';
135
+ import { FormSelectors } from 'my-react-native-project/src/form.selectors';
136
+
137
+ describe('Form', () => {
138
+ it('should input test slowly', async () => {
139
+ await driver.testID$(FormSelectors.Input).slowInput('test', 100);
140
+ });
141
+ });
142
+ ```
143
+
144
+ #### clearInput
145
+
146
+ `clearInput` does several things:
147
+ - clearValue which usually doesn't work
148
+ - setValue('') which usually doesn't work either
149
+ - gets text and deletes it character by character
150
+
151
+ ```ts
152
+ import driver from '@wdio/globals';
153
+ import { FormSelectors } from 'my-react-native-project/src/form.selectors';
154
+
155
+ describe('Form', () => {
156
+ it('should clear input', async () => {
157
+ await driver.testID$(FormSelectors.Input).clearInput();
158
+ });
159
+ });
160
+ ```
161
+
162
+ #### relativeClick
163
+
164
+ `relativeClick` clicks on element relative to it's size in percents
165
+
166
+ ```ts
167
+ import driver from '@wdio/globals';
168
+ import { FormSelectors } from 'my-react-native-project/src/form.selectors';
169
+
170
+ describe('Form', () => {
171
+ it('should click on the center of the element', async () => {
172
+ await driver.testID$(FormSelectors.Button).relativeClick(50, 50);
173
+ });
174
+ });
175
+ ```
176
+
177
+
178
+ ## Components
179
+
180
+ ### createComponent
181
+
182
+ `createComponent` is a helper function to create wdio components with testID support
183
+
184
+ ```ts
185
+ import { createComponent } from '@rnw-community/wdio';
186
+ import { CardSelectors } from 'my-react-native-project/src/card.selectors';
187
+
188
+ describe('Card', () => {
189
+ it('should find component', async () => {
190
+ const card = createComponent(CardSelectors);
191
+ const cards = await card.els();
192
+ await expect(cards).toHaveLength(3);
193
+
194
+ const lastCard = await card.byIdx(2);
195
+ await expect(lastCard.Root).toBeDisplayed();
196
+ await expect(lastCard.Text).toHaveText('Card 3');
197
+ await lastCard.CloseButton.click();
198
+ await expect(card.els()).resolves.toHaveLength(2);
199
+ });
200
+ });
201
+ ```
202
+
203
+ ### getComponent
204
+
205
+ `getComponent` is a helper function to get wdio component class with testID support
206
+
207
+ #### card.component.ts
208
+ ```ts
209
+ import { getComponent } from '@rnw-community/wdio';
210
+ import { CardSelectors } from 'my-react-native-project/src/card.selectors';
211
+
212
+ export class Card extends getComponent(CardSelectors) {
213
+ public async close() {
214
+ await this.CloseButton.click();
215
+ }
216
+ }
217
+ ```
218
+ #### card.spec.ts
219
+ ```ts
220
+ import { Card } from './card.component';
221
+
222
+ describe('Card', () => {
223
+ it('should find component', async () => {
224
+ const card = new Card();
225
+ const cards = await card.els();
226
+ await expect(cards).toHaveLength(3);
227
+
228
+ const lastCard = await card.byIdx(2);
229
+ await expect(lastCard.Root).toBeDisplayed();
230
+ await expect(lastCard.Text).toHaveText('Card 3');
231
+ // no need to use lastCard.CloseButton.click();
232
+ await lastCard.close();
233
+ await expect(card.els()).resolves.toHaveLength(2);
234
+ });
235
+ });
236
+ ```
237
+
238
+ ### createRootedComponent
239
+
240
+ `createRootedComponent` is a helper function to create wdio components with testID support and root element
241
+
242
+ ```ts
243
+ import { createRootedComponent } from '@rnw-community/wdio';
244
+ import { CardSelectors } from 'my-react-native-project/src/card.selectors';
245
+
246
+ describe('Card', () => {
247
+ it('should find component', async () => {
248
+ const card = createRootedComponent(CardSelectors);
249
+ const cards = await card.els();
250
+ await expect(cards).toHaveLength(3);
251
+
252
+ const lastCard = await card.byIdx(2);
253
+ // no need to use lastCard.Root because it's already in the Card class
254
+ await expect(lastCard).toBeDisplayed();
255
+ await expect(lastCard.Text).toHaveText('Card 3');
256
+ await lastCard.CloseButton.click();
257
+ await expect(card.els()).resolves.toHaveLength(2);
258
+ });
259
+ });
260
+ ```
261
+ ### getRootedComponent
262
+
263
+ `getRootedComponent` is a helper function to get wdio component class with testID support and root element
264
+
265
+ #### card.component.ts
266
+ ```ts
267
+ import { getRootedComponent } from '@rnw-community/wdio';
268
+ import { CardSelectors } from 'my-react-native-project/src/card.selectors';
269
+
270
+ export class Card extends getRootedComponent(CardSelectors) {
271
+ public async close() {
272
+ await this.CloseButton.click();
273
+ }
274
+ }
275
+ ```
276
+ #### card.spec.ts
277
+ ```ts
278
+ import { Card } from './card.component';
279
+
280
+ describe('Card', () => {
281
+ it('should find component', async () => {
282
+ const card = new Card();
283
+ const cards = await card.els();
284
+ await expect(cards).toHaveLength(3);
285
+
286
+ const lastCard = await card.byIdx(2);
287
+ // no need to use lastCard.Root because it's already in the Card class
288
+ await expect(lastCard).toBeDisplayed();
289
+ await expect(lastCard.Text).toHaveText('Card 3');
290
+ // no need to use lastCard.CloseButton.click();
291
+ await lastCard.close();
292
+ await expect(card.els()).resolves.toHaveLength(2);
293
+ });
294
+ });
295
+ ```
296
+ ## Recommendations
297
+
298
+ ### Create Selectors enum for each component close to the component file
299
+
300
+ #### card.selectors.ts
301
+ ```tsx
302
+ export enum CardSelectors {
303
+ Root = 'Root',
304
+ Text = 'Text',
305
+ }
306
+ ```
307
+
308
+ #### card.tsx
309
+ ```tsx
310
+ import { CardSelectors as Selectors } from './card.selectors';
311
+ export const Card = () => (
312
+ <View {...setTestID(CardSelectors.Root)}>
313
+ <Text {...setTestID(CardSelectors.Text)}>Text</Text>
314
+ </View>
315
+ );
316
+ ```
317
+ ### Export all selectors from your project in selectors.ts file in your src folder
318
+
319
+ #### selectors.ts
320
+ ```tsx
321
+ export * from './card/card.selectors';
322
+ ```
323
+