@progress/kendo-e2e 4.11.2 → 4.12.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.
- package/README.md +33 -111
- package/dist/selenium/browser.d.ts +245 -4
- package/dist/selenium/browser.js +245 -4
- package/dist/selenium/browser.js.map +1 -1
- package/dist/selenium/conditions.d.ts +255 -0
- package/dist/selenium/conditions.js +251 -0
- package/dist/selenium/conditions.js.map +1 -1
- package/dist/selenium/driver-manager.d.ts +123 -0
- package/dist/selenium/driver-manager.js +118 -0
- package/dist/selenium/driver-manager.js.map +1 -1
- package/dist/selenium/electron-app.d.ts +32 -2
- package/dist/selenium/electron-app.js +32 -2
- package/dist/selenium/electron-app.js.map +1 -1
- package/dist/selenium/expect.d.ts +227 -0
- package/dist/selenium/expect.js +22 -0
- package/dist/selenium/expect.js.map +1 -1
- package/dist/selenium/web-app.d.ts +779 -9
- package/dist/selenium/web-app.js +778 -9
- package/dist/selenium/web-app.js.map +1 -1
- package/docs/API_REFERENCE.md +1309 -0
- package/docs/GETTING_STARTED.md +337 -0
- package/docs/PATTERNS.md +629 -0
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -1,130 +1,52 @@
|
|
|
1
|
-
|
|
2
|
-

|
|
3
|
-
|
|
4
|
-
## Professional Grade UI Components
|
|
5
|
-
|
|
6
|
-
This package is part of the [Kendo UI for Angular](https://www.telerik.com/kendo-angular-ui/) and [KendoReact](https://www.telerik.com/kendo-react-ui/components/#react-components) suites.
|
|
7
|
-
|
|
8
|
-
## License
|
|
9
|
-
|
|
10
|
-
This is commercial software. To use it, you need to agree to the [**Telerik End User License Agreement for Kendo UI** (for Kendo UI for Angular)](http://www.telerik.com/purchase/license-agreement/kendo-ui) or to the [**End User License Agreement for Progress KendoReact** (for KendoReact)](https://www.telerik.com/purchase/license-agreement/progress-kendoreact). If you do not own a commercial license, this file shall be governed by the trial license terms.
|
|
11
|
-
|
|
12
|
-
All available Kendo UI commercial licenses may be obtained at http://www.telerik.com/purchase/kendo-ui.
|
|
13
|
-
|
|
14
|
-
## Kendo UI for Angular Resources and Feedback
|
|
15
|
-
|
|
16
|
-
- [Get Started](https://www.telerik.com/kendo-angular-ui/getting-started)
|
|
17
|
-
- [Component References](https://www.telerik.com/kendo-angular-ui/components)
|
|
18
|
-
- [Blogs](http://www.telerik.com/blogs/kendo-ui)
|
|
19
|
-
- [FAQ](https://www.telerik.com/kendo-angular-ui/components/faq/)
|
|
20
|
-
- [GitHub Issues](https://github.com/telerik/kendo-angular/issues)
|
|
21
|
-
- [Feedback Portal](http://kendoui-feedback.telerik.com/forums/555517-kendo-ui-for-angular-2-feedback)
|
|
22
|
-
- [StackOverflow](https://stackoverflow.com/questions/tagged/kendo-ui-angular2)
|
|
23
|
-
|
|
24
|
-
## KendoReact Resources and Feedback
|
|
25
|
-
|
|
26
|
-
- [Get Started](https://www.telerik.com/kendo-react-ui/getting-started)
|
|
27
|
-
- [Component References](https://www.telerik.com/kendo-react-ui/components/#react-components)
|
|
28
|
-
- [Blogs](http://www.telerik.com/blogs/kendo-ui)
|
|
29
|
-
- [GitHub Issues](https://github.com/telerik/kendo-react/issues)
|
|
30
|
-
- [Feedback Portal](http://kendoui-feedback.telerik.com/forums/908425-kendo-ui-for-react-feedback)
|
|
31
|
-
- [StackOverflow](https://stackoverflow.com/questions/tagged/kendo-react-ui)
|
|
32
|
-
|
|
33
|
-
*Copyright © 2021 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.*
|
|
34
|
-
|
|
35
|
-
*Progress, Telerik, and certain product names used herein are trademarks or registered trademarks of Progress Software Corporation and/or one of its subsidiaries or affiliates in the U.S. and/or other countries.*
|
|
36
|
-
|
|
37
1
|
# kendo-e2e
|
|
38
2
|
|
|
39
3
|
Selenium based e2e testing for web.
|
|
40
4
|
|
|
41
|
-
##
|
|
42
|
-
|
|
43
|
-
### Managing browsers
|
|
44
|
-
|
|
45
|
-
Example:
|
|
46
|
-
|
|
47
|
-
```javascript
|
|
48
|
-
const browser = new Browser();
|
|
49
|
-
await browser.navigateTo("https://www.telerik.com/")
|
|
50
|
-
await browser.close();
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
By default it will start Chrome browser with size 1366x768.
|
|
54
|
-
|
|
55
|
-
Browser type and size can be controlled by settings following environment variables:
|
|
56
|
-
|
|
57
|
-
- `BROWSER_NAME`
|
|
58
|
-
|
|
59
|
-
Allowed values are `chrome`, `firefox`, `MicrosoftEdge` and `safari` (default is `chrome`).
|
|
5
|
+
## Getting Started
|
|
60
6
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
Default values are `1366` and `768`.
|
|
64
|
-
|
|
65
|
-
- `HEADLESS`
|
|
66
|
-
|
|
67
|
-
If set to `true` it will start browsers in headless mode (default is `false`).
|
|
68
|
-
|
|
69
|
-
Notes: `Safari` do not support headless mode and this setting will be ignored.
|
|
70
|
-
|
|
71
|
-
### Find Elements and Wait for Conditions
|
|
72
|
-
|
|
73
|
-
Selenium default behavior when you search for element is to return it if available and throw if not available (do not try to wait until element is available).
|
|
74
|
-
|
|
75
|
-
To make writing e2e tests easier and tests more stable in `kendo-e2e` we have:
|
|
76
|
-
|
|
77
|
-
```js
|
|
78
|
-
const element = await browser.find(locator, timeout);
|
|
7
|
+
```bash
|
|
8
|
+
npm install @progress/kendo-e2e --save-dev
|
|
79
9
|
```
|
|
80
10
|
|
|
81
|
-
|
|
11
|
+
```typescript
|
|
12
|
+
import { Browser } from '@progress/kendo-e2e';
|
|
82
13
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
```js
|
|
86
|
-
await browser.getErrorLogs()
|
|
87
|
-
```
|
|
14
|
+
describe('My First Test', () => {
|
|
15
|
+
let browser: Browser;
|
|
88
16
|
|
|
89
|
-
|
|
17
|
+
beforeAll(async () => {
|
|
18
|
+
browser = new Browser();
|
|
19
|
+
});
|
|
90
20
|
|
|
91
|
-
|
|
21
|
+
afterAll(async () => {
|
|
22
|
+
await browser.close();
|
|
23
|
+
});
|
|
92
24
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
25
|
+
it('should load page and interact', async () => {
|
|
26
|
+
await browser.navigateTo('https://example.com');
|
|
27
|
+
await browser.click('#login-button');
|
|
28
|
+
await browser.type('#username', 'testuser');
|
|
29
|
+
await browser.expect('.welcome-message').toBeVisible();
|
|
30
|
+
});
|
|
31
|
+
});
|
|
97
32
|
```
|
|
98
33
|
|
|
99
|
-
|
|
34
|
+
## Documentation
|
|
100
35
|
|
|
101
|
-
|
|
36
|
+
- [Getting Started](./docs/GETTING_STARTED.md) - Quick start guide and basic usage
|
|
37
|
+
- [API Reference](./docs/API_REFERENCE.md) - Complete API documentation
|
|
38
|
+
- [Common Patterns](./docs/PATTERNS.md) - Real-world testing patterns and best practices
|
|
102
39
|
|
|
103
|
-
|
|
40
|
+
### AI/Copilot Integration
|
|
104
41
|
|
|
105
|
-
|
|
42
|
+
To get better AI-powered suggestions when writing tests, you can create a `.github/copilot-instructions.md` file in your project:
|
|
106
43
|
|
|
107
|
-
|
|
44
|
+
```markdown
|
|
45
|
+
When writing e2e tests with @progress/kendo-e2e, refer to the documentation in
|
|
46
|
+
node_modules/@progress/kendo-e2e/docs/ for patterns, API usage, and best practices.
|
|
108
47
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
Build:
|
|
116
|
-
|
|
117
|
-
```bash
|
|
118
|
-
npm run build
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
Run tests:
|
|
122
|
-
|
|
123
|
-
```bash
|
|
124
|
-
npm run test:a11y
|
|
125
|
-
npm run test:e2e
|
|
126
|
-
npm run test:visual
|
|
127
|
-
npm run test:components
|
|
128
|
-
npm run test:rendering
|
|
129
|
-
npm run test:snapshot
|
|
48
|
+
Key points:
|
|
49
|
+
- Browser is started once in beforeAll, closed in afterAll
|
|
50
|
+
- All interactions have automatic waiting built-in
|
|
51
|
+
- Avoid Page Object pattern for simple component tests
|
|
130
52
|
```
|
|
@@ -14,10 +14,46 @@ interface BrowserOptions {
|
|
|
14
14
|
enableBidi?: boolean;
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* and
|
|
17
|
+
* Browser automation class with automatic waiting and modern web testing features.
|
|
18
|
+
*
|
|
19
|
+
* Extends {@link WebApp} with browser-specific capabilities like navigation, window management,
|
|
20
|
+
* accessibility testing, and console log monitoring. Perfect for testing web applications in
|
|
21
|
+
* real browsers (Chrome, Firefox, Safari, Edge).
|
|
22
|
+
*
|
|
23
|
+
* **Key features:**
|
|
24
|
+
* - Browser navigation and URL management
|
|
25
|
+
* - Window resizing and iframe handling
|
|
26
|
+
* - Mobile device emulation
|
|
27
|
+
* - Accessibility (a11y) testing with axe-core
|
|
28
|
+
* - Console error detection
|
|
29
|
+
* - BiDi protocol support
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* // Basic browser test
|
|
34
|
+
* const browser = new Browser();
|
|
35
|
+
* await browser.navigateTo('https://example.com');
|
|
36
|
+
* await browser.click('#login-button');
|
|
37
|
+
* await browser.expect('.welcome-message').toBeVisible();
|
|
38
|
+
* await browser.close();
|
|
39
|
+
*
|
|
40
|
+
* // Mobile emulation
|
|
41
|
+
* const mobile = new Browser({ mobileEmulation: { deviceName: 'iPhone 14 Pro Max' } });
|
|
42
|
+
* await mobile.navigateTo('https://example.com');
|
|
43
|
+
*
|
|
44
|
+
* // With BiDi for advanced features
|
|
45
|
+
* const browser = new Browser({ enableBidi: true });
|
|
46
|
+
*
|
|
47
|
+
* // Check for console errors
|
|
48
|
+
* await browser.clearLogs();
|
|
49
|
+
* await browser.click('#trigger-error');
|
|
50
|
+
* const errors = await browser.getErrorLogs();
|
|
51
|
+
* expect(errors).toHaveLength(0);
|
|
52
|
+
*
|
|
53
|
+
* // Accessibility testing
|
|
54
|
+
* const violations = await browser.getAccessibilityViolations();
|
|
55
|
+
* expect(violations).toHaveLength(0);
|
|
56
|
+
* ```
|
|
21
57
|
*/
|
|
22
58
|
export declare class Browser extends WebApp {
|
|
23
59
|
/**
|
|
@@ -70,7 +106,47 @@ export declare class Browser extends WebApp {
|
|
|
70
106
|
height: number;
|
|
71
107
|
pixelRatio: number;
|
|
72
108
|
} | any, enableBidi?: boolean);
|
|
109
|
+
/**
|
|
110
|
+
* Closes the browser and ends the WebDriver session.
|
|
111
|
+
*
|
|
112
|
+
* Should be called at the end of each test to clean up resources.
|
|
113
|
+
* Closes all browser windows and terminates the driver.
|
|
114
|
+
*
|
|
115
|
+
* @returns Promise that resolves when browser is closed
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```typescript
|
|
119
|
+
* const browser = new Browser();
|
|
120
|
+
* try {
|
|
121
|
+
* await browser.navigateTo('https://example.com');
|
|
122
|
+
* // ... test code ...
|
|
123
|
+
* } finally {
|
|
124
|
+
* await browser.close(); // Always close to free resources
|
|
125
|
+
* }
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
73
128
|
close(): Promise<void>;
|
|
129
|
+
/**
|
|
130
|
+
* Navigates the browser to a specified URL.
|
|
131
|
+
*
|
|
132
|
+
* Opens the URL in the current browser window. Waits for the page to load before
|
|
133
|
+
* the promise resolves.
|
|
134
|
+
*
|
|
135
|
+
* @param url - The URL to navigate to (must include protocol: http:// or https://)
|
|
136
|
+
* @returns Promise that resolves when navigation completes
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```typescript
|
|
140
|
+
* // Navigate to a website
|
|
141
|
+
* await browser.navigateTo('https://example.com');
|
|
142
|
+
*
|
|
143
|
+
* // Navigate to local development server
|
|
144
|
+
* await browser.navigateTo('http://localhost:3000');
|
|
145
|
+
*
|
|
146
|
+
* // Navigate to specific page
|
|
147
|
+
* await browser.navigateTo('https://example.com/products/123');
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
74
150
|
navigateTo(url: string): Promise<void>;
|
|
75
151
|
getRect(): Promise<IRectangle>;
|
|
76
152
|
setRect(rect: {
|
|
@@ -97,12 +173,177 @@ export declare class Browser extends WebApp {
|
|
|
97
173
|
* ```
|
|
98
174
|
*/
|
|
99
175
|
resizeWindow(width: number, height: number): Promise<void>;
|
|
176
|
+
/**
|
|
177
|
+
* Refreshes the current page (like pressing F5 or clicking browser refresh).
|
|
178
|
+
*
|
|
179
|
+
* Reloads the page from the server, resetting all JavaScript state.
|
|
180
|
+
*
|
|
181
|
+
* @returns Promise that resolves when page reload completes
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```typescript
|
|
185
|
+
* // Refresh after making changes
|
|
186
|
+
* await browser.click('#update-settings');
|
|
187
|
+
* await browser.refresh();
|
|
188
|
+
*
|
|
189
|
+
* // Verify data persists after refresh
|
|
190
|
+
* await browser.type('#input', 'test');
|
|
191
|
+
* await browser.click('#save');
|
|
192
|
+
* await browser.refresh();
|
|
193
|
+
* const value = await browser.getAttribute('#input', 'value');
|
|
194
|
+
* expect(value).toBe('test');
|
|
195
|
+
* ```
|
|
196
|
+
*/
|
|
100
197
|
refresh(): Promise<void>;
|
|
198
|
+
/**
|
|
199
|
+
* Switches the WebDriver context to an iframe.
|
|
200
|
+
*
|
|
201
|
+
* After calling this, all subsequent commands will target elements within the iframe.
|
|
202
|
+
* To switch back to the main page, use `driver.switchTo().defaultContent()`.
|
|
203
|
+
*
|
|
204
|
+
* @param elementLocator - By locator for the iframe element
|
|
205
|
+
* @returns Promise that resolves when context is switched
|
|
206
|
+
*
|
|
207
|
+
* @example
|
|
208
|
+
* ```typescript
|
|
209
|
+
* // Switch to iframe and interact with its content
|
|
210
|
+
* await browser.switchToIFrame(By.css('#my-iframe'));
|
|
211
|
+
* await browser.click('#button-inside-iframe');
|
|
212
|
+
*
|
|
213
|
+
* // Switch back to main page
|
|
214
|
+
* await browser.driver.switchTo().defaultContent();
|
|
215
|
+
* await browser.click('#button-on-main-page');
|
|
216
|
+
*
|
|
217
|
+
* // Work with nested iframes
|
|
218
|
+
* await browser.switchToIFrame(By.css('#outer-frame'));
|
|
219
|
+
* await browser.switchToIFrame(By.css('#inner-frame'));
|
|
220
|
+
* ```
|
|
221
|
+
*/
|
|
101
222
|
switchToIFrame(elementLocator: By): Promise<void>;
|
|
223
|
+
/**
|
|
224
|
+
* Gets the current URL of the browser.
|
|
225
|
+
*
|
|
226
|
+
* Returns the complete URL including protocol, domain, path, and query parameters.
|
|
227
|
+
*
|
|
228
|
+
* @returns Promise resolving to the current URL string
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* ```typescript
|
|
232
|
+
* // Verify navigation occurred
|
|
233
|
+
* await browser.click('#products-link');
|
|
234
|
+
* const url = await browser.getCurrentUrl();
|
|
235
|
+
* expect(url).toContain('/products');
|
|
236
|
+
*
|
|
237
|
+
* // Check URL parameters
|
|
238
|
+
* const currentUrl = await browser.getCurrentUrl();
|
|
239
|
+
* expect(currentUrl).toContain('?filter=active');
|
|
240
|
+
*
|
|
241
|
+
* // Verify redirect
|
|
242
|
+
* await browser.navigateTo('http://example.com/old-page');
|
|
243
|
+
* const redirectedUrl = await browser.getCurrentUrl();
|
|
244
|
+
* expect(redirectedUrl).toBe('http://example.com/new-page');
|
|
245
|
+
* ```
|
|
246
|
+
*/
|
|
102
247
|
getCurrentUrl(): Promise<string>;
|
|
248
|
+
/**
|
|
249
|
+
* Gets the name of the current browser.
|
|
250
|
+
*
|
|
251
|
+
* Returns lowercase browser name: 'chrome', 'firefox', 'safari', 'edge', etc.
|
|
252
|
+
* Useful for browser-specific test logic.
|
|
253
|
+
*
|
|
254
|
+
* @returns Promise resolving to lowercase browser name
|
|
255
|
+
*
|
|
256
|
+
* @example
|
|
257
|
+
* ```typescript
|
|
258
|
+
* const browserName = await browser.getBrowserName();
|
|
259
|
+
*
|
|
260
|
+
* if (browserName === 'safari') {
|
|
261
|
+
* // Skip Safari-incompatible test
|
|
262
|
+
* console.log('Skipping on Safari');
|
|
263
|
+
* return;
|
|
264
|
+
* }
|
|
265
|
+
*
|
|
266
|
+
* // Browser-specific assertions
|
|
267
|
+
* if (browserName === 'firefox') {
|
|
268
|
+
* // Firefox-specific validation
|
|
269
|
+
* }
|
|
270
|
+
* ```
|
|
271
|
+
*/
|
|
103
272
|
getBrowserName(): Promise<string>;
|
|
273
|
+
/**
|
|
274
|
+
* Runs accessibility (a11y) tests using axe-core and returns violations.
|
|
275
|
+
*
|
|
276
|
+
* Scans the page for accessibility issues like missing alt text, insufficient color contrast,
|
|
277
|
+
* missing ARIA labels, etc. Returns an array of violations that should be addressed.
|
|
278
|
+
*
|
|
279
|
+
* @param cssSelector - CSS selector to limit scanning scope (default: 'html' for full page)
|
|
280
|
+
* @param disableRules - Array of axe rule IDs to disable (default: ['color-contrast'])
|
|
281
|
+
* @returns Promise resolving to array of accessibility violations
|
|
282
|
+
*
|
|
283
|
+
* @example
|
|
284
|
+
* ```typescript
|
|
285
|
+
* // Scan entire page
|
|
286
|
+
* const violations = await browser.getAccessibilityViolations();
|
|
287
|
+
* expect(violations).toHaveLength(0);
|
|
288
|
+
*
|
|
289
|
+
* // Scan specific component
|
|
290
|
+
* const formViolations = await browser.getAccessibilityViolations('#login-form');
|
|
291
|
+
*
|
|
292
|
+
* // Enable all rules including color contrast
|
|
293
|
+
* const allViolations = await browser.getAccessibilityViolations('html', []);
|
|
294
|
+
*
|
|
295
|
+
* // Disable specific rules
|
|
296
|
+
* const violations = await browser.getAccessibilityViolations('html', [
|
|
297
|
+
* 'color-contrast',
|
|
298
|
+
* 'landmark-one-main'
|
|
299
|
+
* ]);
|
|
300
|
+
* ```
|
|
301
|
+
*/
|
|
104
302
|
getAccessibilityViolations(cssSelector?: string, disableRules?: string[]): Promise<[]>;
|
|
303
|
+
/**
|
|
304
|
+
* Clears the browser console logs.
|
|
305
|
+
*
|
|
306
|
+
* Call this before performing actions to get a clean slate for error detection.
|
|
307
|
+
* Useful when you want to check if a specific action causes console errors.
|
|
308
|
+
*
|
|
309
|
+
* @returns Promise that resolves when logs are cleared
|
|
310
|
+
*
|
|
311
|
+
* @example
|
|
312
|
+
* ```typescript
|
|
313
|
+
* // Clear logs before action
|
|
314
|
+
* await browser.clearLogs();
|
|
315
|
+
* await browser.click('#potential-error-button');
|
|
316
|
+
* const errors = await browser.getErrorLogs();
|
|
317
|
+
* ```
|
|
318
|
+
*/
|
|
105
319
|
clearLogs(): Promise<void>;
|
|
320
|
+
/**
|
|
321
|
+
* Gets console errors from the browser (Chrome only).
|
|
322
|
+
*
|
|
323
|
+
* Retrieves console errors logged by the browser. Only works in Chrome on desktop platforms.
|
|
324
|
+
* Firefox and mobile platforms don't support log retrieval.
|
|
325
|
+
*
|
|
326
|
+
* @param excludeList - Array of strings to filter out from errors (default: ['favicon.ico'])
|
|
327
|
+
* @param logLevel - Minimum log level to collect (default: Level.SEVERE for errors)
|
|
328
|
+
* @returns Promise resolving to array of error message strings
|
|
329
|
+
*
|
|
330
|
+
* @example
|
|
331
|
+
* ```typescript
|
|
332
|
+
* // Check for any console errors
|
|
333
|
+
* const errors = await browser.getErrorLogs();
|
|
334
|
+
* expect(errors.length).toBe(0);
|
|
335
|
+
*
|
|
336
|
+
* // Exclude known non-critical errors
|
|
337
|
+
* const errors = await browser.getErrorLogs(['favicon', 'analytics']);
|
|
338
|
+
*
|
|
339
|
+
* // Get all warnings and errors
|
|
340
|
+
* const logs = await browser.getErrorLogs([], Level.WARNING);
|
|
341
|
+
*
|
|
342
|
+
* // Check for specific error
|
|
343
|
+
* const errors = await browser.getErrorLogs();
|
|
344
|
+
* expect(errors.some(e => e.includes('TypeError'))).toBe(false);
|
|
345
|
+
* ```
|
|
346
|
+
*/
|
|
106
347
|
getErrorLogs(excludeList?: string[], logLevel?: Level): Promise<string[]>;
|
|
107
348
|
/**
|
|
108
349
|
* Executes a JavaScript script in the browser context.
|