@umbraco/playwright-testhelpers 17.0.18 → 17.0.19

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 CHANGED
@@ -1,48 +1,158 @@
1
- # Umbraco.Playwright.Testhelpers
2
- This package contains the Test-helpers for the Umbraco Playwright tests!
1
+ # Umbraco Playwright Test Helpers
2
+
3
+ Test helpers for writing Playwright end-to-end tests for Umbraco CMS.
4
+
5
+ **Repository:** https://github.com/umbraco/umbraco-playwright-testhelpers
3
6
 
4
7
  ## Prerequisites
5
- This project was made with Node V16, so the minimum requirement is node `16.17.1`
6
- Having playwright installed, you can install playwright by running `npx playwright install`
7
8
 
8
- ## Getting started
9
- You can import a helper into your code like so
9
+ - **Node.js:** Minimum version `16.17.1`
10
+ - **Playwright:** Install via `npx playwright install`
10
11
 
12
+ ## Installation
13
+
14
+ ```bash
15
+ npm install @umbraco/playwright-testhelpers
11
16
  ```
12
- import { ConstantHelper } from "@umbraco/playwright-testhelpers";
13
- ```
14
17
 
15
- You can then use it in your code like so:
18
+ ## Usage
19
+
20
+ ### Basic Test Setup
21
+
22
+ Import the `test` fixture from the package to get access to `umbracoApi` and `umbracoUi` helpers:
23
+
24
+ ```typescript
25
+ import { test } from "@umbraco/playwright-testhelpers";
26
+
27
+ test('my test', async ({ umbracoApi, umbracoUi }) => {
28
+ // Your test code here
29
+ });
16
30
  ```
17
- let settingsSection = ConstantHelper.sections.settings;
31
+
32
+ ### API Helpers
33
+
34
+ Use API helpers for test setup, teardown, and backend verification:
35
+
36
+ ```typescript
37
+ import { test } from "@umbraco/playwright-testhelpers";
38
+
39
+ test('create document type via API', async ({ umbracoApi }) => {
40
+ const name = 'TestDocType';
41
+
42
+ // Cleanup before test
43
+ await umbracoApi.documentType.ensureNameNotExists(name);
44
+
45
+ // Create via API
46
+ await umbracoApi.documentType.createDefaultDocumentType(name);
47
+
48
+ // Cleanup after test
49
+ await umbracoApi.documentType.ensureNameNotExists(name);
50
+ });
18
51
  ```
19
52
 
20
- ## Contributing to Umbraco.Playwright.Testhelpers
53
+ ### UI Helpers
21
54
 
22
- ### Adding new helpers
23
- When adding new helpers, it is important to add them as properties in the `ApiHelpers.ts` class
24
- Lets say we have just created a `MacroApiHelper`, first we would need to import it at the top in the `ApiHelpers.ts` file like so:
55
+ Use UI helpers for browser-based interactions:
56
+
57
+ ```typescript
58
+ import { test } from "@umbraco/playwright-testhelpers";
59
+
60
+ test('create content via UI', async ({ umbracoUi }) => {
61
+ await umbracoUi.goToBackOffice();
62
+ await umbracoUi.content.clickActionsMenuAtRoot();
63
+ await umbracoUi.content.clickCreateButton();
64
+ });
25
65
  ```
26
- import {MacroApiHelper} from "./MacroApiHelper";
66
+
67
+ ### Combined API and UI Testing
68
+
69
+ A common pattern is using API helpers for setup/teardown and UI helpers for the actual test:
70
+
71
+ ```typescript
72
+ import { test } from "@umbraco/playwright-testhelpers";
73
+
74
+ test('edit document type', async ({ umbracoApi, umbracoUi }) => {
75
+ const name = 'TestDocType';
76
+
77
+ // Setup via API
78
+ await umbracoApi.documentType.ensureNameNotExists(name);
79
+ await umbracoApi.documentType.createDefaultDocumentType(name);
80
+
81
+ // Test via UI
82
+ await umbracoUi.goToBackOffice();
83
+ await umbracoUi.documentType.goToDocumentType(name);
84
+
85
+ // Cleanup via API
86
+ await umbracoApi.documentType.ensureNameNotExists(name);
87
+ });
27
88
  ```
28
- Then, add it as a property
89
+
90
+ ### Constants and Utilities
91
+
92
+ ```typescript
93
+ import { ConstantHelper, AliasHelper, NotificationConstantHelper } from "@umbraco/playwright-testhelpers";
94
+
95
+ // Access UI sections
96
+ const settingsSection = ConstantHelper.sections.settings;
97
+
98
+ // Convert strings to aliases
99
+ const alias = AliasHelper.toAlias('My Document Type'); // 'myDocumentType'
100
+
101
+ // Access notification messages
102
+ const successMsg = NotificationConstantHelper.success.created;
29
103
  ```
104
+
105
+ ## Available Helpers
106
+
107
+ ### API Helpers (`umbracoApi.*`)
108
+
109
+ `dataType`, `dictionary`, `document`, `documentBlueprint`, `documentType`, `healthCheck`, `indexer`, `language`, `login`, `logViewer`, `media`, `mediaType`, `member`, `memberGroup`, `memberType`, `modelsBuilder`, `objectTypes`, `package`, `partialView`, `publishedCache`, `redirectManagement`, `relationType`, `script`, `smtp`, `stylesheet`, `telemetry`, `template`, `temporaryFile`, `user`, `userGroup`, `webhook`
110
+
111
+ ### UI Helpers (`umbracoUi.*`)
112
+
113
+ `content`, `contentRender`, `currentUserProfile`, `dataType`, `dictionary`, `documentBlueprint`, `documentType`, `examineManagement`, `externalLogin`, `form`, `healthCheck`, `install`, `language`, `login`, `logViewer`, `media`, `mediaType`, `member`, `memberGroup`, `memberType`, `modelsBuilder`, `package`, `partialView`, `profiling`, `publishedStatus`, `redirectManagement`, `relationType`, `script`, `stylesheet`, `telemetryData`, `template`, `user`, `userGroup`, `webhook`, `welcomeDashboard`
114
+
115
+ ## Configuration
116
+
117
+ ### Environment Variables
118
+
119
+ | Variable | Description | Default |
120
+ |----------|-------------|---------|
121
+ | `URL` | Umbraco base URL | `https://localhost:44339` |
122
+ | `UMBRACO_USER_LOGIN` | Admin user email | `nge@umbraco.dk` |
123
+ | `UMBRACO_USER_PASSWORD` | Admin user password | `1234567890` |
124
+ | `UMBRACO_MEMBER_LOGIN` | Test member email | `member@example.com` |
125
+ | `UMBRACO_MEMBER_PASSWORD` | Test member password | `Umbraco9Rocks!` |
126
+
127
+ ## Contributing
128
+
129
+ ### Adding New Helpers
130
+
131
+ 1. Create your helper file (e.g., `MacroApiHelper.ts`)
132
+
133
+ 2. Import and add as a property in `ApiHelpers.ts`:
134
+ ```typescript
135
+ import { MacroApiHelper } from "./MacroApiHelper";
136
+
30
137
  export class ApiHelpers {
31
- macros: MacroApiHelper;
32
- ...
33
- }
138
+ macro: MacroApiHelper;
139
+
140
+ constructor(page: Page) {
141
+ this.macro = new MacroApiHelper(this);
142
+ }
143
+ }
34
144
  ```
35
145
 
36
- Then, use the constructor to populate the property
146
+ 3. For UI helpers, extend `UiBaseLocators` and add to `UiHelpers.ts`
37
147
 
148
+ ### Testing Changes Locally
149
+
150
+ ```bash
151
+ npm run build
152
+ npm pack
153
+ npm i /path/to/umbraco-playwright-testhelpers-x.x.x.tgz
38
154
  ```
39
- constructor(page: Page) {
40
- this.macros = new MacroApiHelper(this);
41
- ...
42
- }
43
- ```
44
155
 
45
- ### Testing your changes locally
46
- When you have changes you want to test, you can run `npm run build` & `npm pack` in the root of this folder, You will need to copy the absolute path of the file you just created with `npm pack`.
47
- then run `npm i absolute path to your file` in the project where you are using this package. An example could be `npm i C:\Users\ABC\Desktop\Umbraco.Playwright.Testhelpers\umbraco-playwright-testhelpers-1.0.0.tgz`.
48
- If you have new changes, you can follow the same steps as before.
156
+ ## License
157
+
158
+ MIT
@@ -192,6 +192,7 @@ export declare class ContentUiHelper extends UiBaseLocators {
192
192
  waitForModalHidden(): Promise<void>;
193
193
  clickSaveButtonForContent(): Promise<void>;
194
194
  enterTextstring(text: string): Promise<void>;
195
+ isTextstringPropertyVisible(isVisible?: boolean): Promise<void>;
195
196
  doesContentTreeHaveName(contentName: string): Promise<void>;
196
197
  enterRichTextArea(value: string): Promise<void>;
197
198
  enterTextArea(value: string): Promise<void>;
@@ -273,6 +274,7 @@ export declare class ContentUiHelper extends UiBaseLocators {
273
274
  isDocumentTypeNameVisible(contentName: string, isVisible?: boolean): Promise<void>;
274
275
  doesModalHaveText(text: string): Promise<void>;
275
276
  isTabNameVisible(tabName: string): Promise<void>;
277
+ clickTabWithName(tabName: string): Promise<void>;
276
278
  doesDocumentHaveName(name: string): Promise<void>;
277
279
  doesDocumentTableColumnNameValuesMatch(expectedValues: string[]): Promise<void>;
278
280
  searchByKeywordInCollection(keyword: string): Promise<void>;
@@ -455,4 +457,8 @@ export declare class ContentUiHelper extends UiBaseLocators {
455
457
  isAddBlockListElementWithNameVisible(blockName: string): Promise<void>;
456
458
  enterBlockPropertyValue(propertyName: string, value: string): Promise<void>;
457
459
  isBlockPropertyEditable(propertyName: string, isEditable?: boolean): Promise<void>;
460
+ isInlineBlockPropertyVisible(propertyName: string, isVisible?: boolean): Promise<void>;
461
+ isInlineBlockPropertyVisibleForBlockWithName(blockName: string, propertyName: string, isVisible?: boolean, index?: number): Promise<void>;
462
+ enterInlineBlockPropertyValue(propertyName: string, value: string, index?: number): Promise<void>;
463
+ doesInlineBlockPropertyHaveValue(propertyName: string, value: string, index?: number): Promise<void>;
458
464
  }
@@ -432,6 +432,14 @@ class ContentUiHelper extends UiBaseLocators_1.UiBaseLocators {
432
432
  await this.textstringTxt.clear();
433
433
  await this.textstringTxt.fill(text);
434
434
  }
435
+ async isTextstringPropertyVisible(isVisible = true) {
436
+ if (isVisible) {
437
+ await (0, test_1.expect)(this.textstringTxt).toBeVisible();
438
+ }
439
+ else {
440
+ await (0, test_1.expect)(this.textstringTxt).not.toBeVisible();
441
+ }
442
+ }
435
443
  async doesContentTreeHaveName(contentName) {
436
444
  await (0, test_1.expect)(this.contentTree).toContainText(contentName);
437
445
  }
@@ -766,6 +774,11 @@ class ContentUiHelper extends UiBaseLocators_1.UiBaseLocators {
766
774
  async isTabNameVisible(tabName) {
767
775
  return (0, test_1.expect)(this.tabItems.filter({ hasText: tabName })).toBeVisible();
768
776
  }
777
+ async clickTabWithName(tabName) {
778
+ const tabLocator = this.tabItems.filter({ hasText: tabName });
779
+ await (0, test_1.expect)(tabLocator).toBeVisible();
780
+ await tabLocator.click();
781
+ }
769
782
  async doesDocumentHaveName(name) {
770
783
  return (0, test_1.expect)(this.enterAName).toHaveValue(name);
771
784
  }
@@ -1568,6 +1581,25 @@ class ContentUiHelper extends UiBaseLocators_1.UiBaseLocators {
1568
1581
  await (0, test_1.expect)(propertyLocator).toBeVisible();
1569
1582
  await (0, test_1.expect)(propertyLocator).toBeEditable({ editable: isEditable });
1570
1583
  }
1584
+ async isInlineBlockPropertyVisible(propertyName, isVisible = true) {
1585
+ const propertyLocator = this.blockListEntry.locator(this.blockProperty).filter({ hasText: propertyName });
1586
+ await (0, test_1.expect)(propertyLocator).toBeVisible({ visible: isVisible });
1587
+ }
1588
+ async isInlineBlockPropertyVisibleForBlockWithName(blockName, propertyName, isVisible = true, index = 0) {
1589
+ const blockEntryLocator = this.blockListEntry.filter({ hasText: blockName }).nth(index);
1590
+ const propertyLocator = blockEntryLocator.locator(this.blockProperty).filter({ hasText: propertyName });
1591
+ await (0, test_1.expect)(propertyLocator).toBeVisible({ visible: isVisible });
1592
+ }
1593
+ async enterInlineBlockPropertyValue(propertyName, value, index = 0) {
1594
+ const propertyLocator = this.blockListEntry.nth(index).locator(this.blockProperty).filter({ hasText: propertyName });
1595
+ await (0, test_1.expect)(propertyLocator).toBeVisible();
1596
+ await propertyLocator.locator('input').clear();
1597
+ await propertyLocator.locator('input').fill(value);
1598
+ }
1599
+ async doesInlineBlockPropertyHaveValue(propertyName, value, index = 0) {
1600
+ const propertyLocator = this.blockListEntry.nth(index).locator(this.blockProperty).filter({ hasText: propertyName }).locator('input');
1601
+ await (0, test_1.expect)(propertyLocator).toHaveValue(value);
1602
+ }
1571
1603
  }
1572
1604
  exports.ContentUiHelper = ContentUiHelper;
1573
1605
  //# sourceMappingURL=ContentUiHelper.js.map