@pwtap/create 0.1.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 (103) hide show
  1. package/core-manifest.json +50 -0
  2. package/dist/commands/add.d.ts +8 -0
  3. package/dist/commands/add.d.ts.map +1 -0
  4. package/dist/commands/add.js +9 -0
  5. package/dist/commands/add.js.map +1 -0
  6. package/dist/commands/create.d.ts +12 -0
  7. package/dist/commands/create.d.ts.map +1 -0
  8. package/dist/commands/create.js +114 -0
  9. package/dist/commands/create.js.map +1 -0
  10. package/dist/commands/remove.d.ts +7 -0
  11. package/dist/commands/remove.d.ts.map +1 -0
  12. package/dist/commands/remove.js +9 -0
  13. package/dist/commands/remove.js.map +1 -0
  14. package/dist/index.d.ts +3 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +55 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/injectors/assets.d.ts +6 -0
  19. package/dist/injectors/assets.d.ts.map +1 -0
  20. package/dist/injectors/assets.js +53 -0
  21. package/dist/injectors/assets.js.map +1 -0
  22. package/dist/injectors/envJson.d.ts +6 -0
  23. package/dist/injectors/envJson.d.ts.map +1 -0
  24. package/dist/injectors/envJson.js +39 -0
  25. package/dist/injectors/envJson.js.map +1 -0
  26. package/dist/injectors/fixturesBarrel.d.ts +11 -0
  27. package/dist/injectors/fixturesBarrel.d.ts.map +1 -0
  28. package/dist/injectors/fixturesBarrel.js +66 -0
  29. package/dist/injectors/fixturesBarrel.js.map +1 -0
  30. package/dist/injectors/packageJson.d.ts +6 -0
  31. package/dist/injectors/packageJson.d.ts.map +1 -0
  32. package/dist/injectors/packageJson.js +25 -0
  33. package/dist/injectors/packageJson.js.map +1 -0
  34. package/dist/injectors/pwConfig.d.ts +10 -0
  35. package/dist/injectors/pwConfig.d.ts.map +1 -0
  36. package/dist/injectors/pwConfig.js +40 -0
  37. package/dist/injectors/pwConfig.js.map +1 -0
  38. package/dist/manifest.d.ts +65 -0
  39. package/dist/manifest.d.ts.map +1 -0
  40. package/dist/manifest.js +22 -0
  41. package/dist/manifest.js.map +1 -0
  42. package/dist/plugin-apply.d.ts +13 -0
  43. package/dist/plugin-apply.d.ts.map +1 -0
  44. package/dist/plugin-apply.js +89 -0
  45. package/dist/plugin-apply.js.map +1 -0
  46. package/dist/prompts.d.ts +22 -0
  47. package/dist/prompts.d.ts.map +1 -0
  48. package/dist/prompts.js +65 -0
  49. package/dist/prompts.js.map +1 -0
  50. package/dist/registry.d.ts +26 -0
  51. package/dist/registry.d.ts.map +1 -0
  52. package/dist/registry.js +34 -0
  53. package/dist/registry.js.map +1 -0
  54. package/dist/util/fs.d.ts +13 -0
  55. package/dist/util/fs.d.ts.map +1 -0
  56. package/dist/util/fs.js +32 -0
  57. package/dist/util/fs.js.map +1 -0
  58. package/dist/util/log.d.ts +8 -0
  59. package/dist/util/log.d.ts.map +1 -0
  60. package/dist/util/log.js +9 -0
  61. package/dist/util/log.js.map +1 -0
  62. package/dist/util/markers.d.ts +20 -0
  63. package/dist/util/markers.d.ts.map +1 -0
  64. package/dist/util/markers.js +51 -0
  65. package/dist/util/markers.js.map +1 -0
  66. package/dist/util/run.d.ts +8 -0
  67. package/dist/util/run.d.ts.map +1 -0
  68. package/dist/util/run.js +27 -0
  69. package/dist/util/run.js.map +1 -0
  70. package/package.json +31 -0
  71. package/template/.commitlintrc.json +3 -0
  72. package/template/.prettierrc +17 -0
  73. package/template/api/core/ApiClient.ts +99 -0
  74. package/template/api/core/types.ts +29 -0
  75. package/template/api/index.ts +4 -0
  76. package/template/api/models/pet.ts +24 -0
  77. package/template/api/services/PetService.ts +67 -0
  78. package/template/config/envUtils.ts +70 -0
  79. package/template/config/index.ts +2 -0
  80. package/template/config/loadEnv.ts +110 -0
  81. package/template/env/environments.example.json +20 -0
  82. package/template/eslint.config.js +74 -0
  83. package/template/fixtures/api.ts +46 -0
  84. package/template/fixtures/auth.ts +150 -0
  85. package/template/fixtures/index.ts +38 -0
  86. package/template/fixtures/ui.ts +112 -0
  87. package/template/pages/BasePage.ts +225 -0
  88. package/template/pages/LoginPage.ts +50 -0
  89. package/template/pages/index.ts +2 -0
  90. package/template/playwright.config.ts +71 -0
  91. package/template/templates/gitignore +19 -0
  92. package/template/testData/users.example.json +17 -0
  93. package/template/tests/api/pet.api.ts +60 -0
  94. package/template/tests/example/authSession.spec.ts +34 -0
  95. package/template/tests/example/login.spec.ts +50 -0
  96. package/template/tsconfig.json +33 -0
  97. package/template/utils/apiUtils.ts +224 -0
  98. package/template/utils/dateUtils.ts +158 -0
  99. package/template/utils/index.ts +15 -0
  100. package/template/utils/stringUtils.ts +192 -0
  101. package/template/utils/uiUtils.ts +236 -0
  102. package/template/utils/validationUtils.ts +190 -0
  103. package/template/utils/waitUtils.ts +207 -0
@@ -0,0 +1,207 @@
1
+ import type { Locator, Page } from '@playwright/test';
2
+
3
+ /**
4
+ * Wait and Retry Utility Functions
5
+ * Provides wait helpers and retry logic
6
+ */
7
+
8
+ export class WaitUtils {
9
+ /**
10
+ * Wait for specific amount of time
11
+ */
12
+ static async wait(milliseconds: number): Promise<void> {
13
+ await new Promise(resolve => setTimeout(resolve, milliseconds));
14
+ }
15
+
16
+ /**
17
+ * Wait for condition to be true
18
+ */
19
+ static async waitForCondition(
20
+ condition: () => boolean | Promise<boolean>,
21
+ options?: {
22
+ timeout?: number;
23
+ interval?: number;
24
+ errorMessage?: string;
25
+ },
26
+ ): Promise<void> {
27
+ const timeout = options?.timeout || 30000;
28
+ const interval = options?.interval || 500;
29
+ const errorMessage = options?.errorMessage || 'Condition not met within timeout';
30
+ const startTime = Date.now();
31
+
32
+ while (Date.now() - startTime < timeout) {
33
+ if (await condition()) {
34
+ return;
35
+ }
36
+ await this.wait(interval);
37
+ }
38
+
39
+ throw new Error(errorMessage);
40
+ }
41
+
42
+ /**
43
+ * Wait for element count to match expected value
44
+ */
45
+ static async waitForElementCount(
46
+ elements: Locator,
47
+ expectedCount: number,
48
+ timeout: number = 30000,
49
+ ): Promise<void> {
50
+ await this.waitForCondition(async () => (await elements.count()) === expectedCount, {
51
+ timeout,
52
+ errorMessage: `Expected ${expectedCount} elements, but got different count`,
53
+ });
54
+ }
55
+
56
+ /**
57
+ * Wait for text to appear in element
58
+ */
59
+ static async waitForText(element: Locator, text: string, timeout: number = 30000): Promise<void> {
60
+ await element.waitFor({ state: 'visible', timeout });
61
+ await this.waitForCondition(
62
+ async () => {
63
+ const content = await element.textContent();
64
+ return content?.includes(text) || false;
65
+ },
66
+ { timeout, errorMessage: `Text "${text}" did not appear in element` },
67
+ );
68
+ }
69
+
70
+ /**
71
+ * Wait for text to disappear from element
72
+ */
73
+ static async waitForTextToDisappear(
74
+ element: Locator,
75
+ text: string,
76
+ timeout: number = 30000,
77
+ ): Promise<void> {
78
+ await this.waitForCondition(
79
+ async () => {
80
+ const content = await element.textContent();
81
+ return !content?.includes(text);
82
+ },
83
+ { timeout, errorMessage: `Text "${text}" did not disappear from element` },
84
+ );
85
+ }
86
+
87
+ /**
88
+ * Wait for URL to match pattern
89
+ */
90
+ static async waitForURL(
91
+ page: Page,
92
+ urlPattern: string | RegExp,
93
+ timeout: number = 30000,
94
+ ): Promise<void> {
95
+ await page.waitForURL(urlPattern, { timeout });
96
+ }
97
+
98
+ /**
99
+ * Wait for URL to contain text
100
+ */
101
+ static async waitForURLContains(
102
+ page: Page,
103
+ text: string,
104
+ timeout: number = 30000,
105
+ ): Promise<void> {
106
+ await this.waitForCondition(() => page.url().includes(text), {
107
+ timeout,
108
+ errorMessage: `URL does not contain "${text}"`,
109
+ });
110
+ }
111
+
112
+ /**
113
+ * Wait for page to be fully loaded
114
+ */
115
+ static async waitForPageLoad(
116
+ page: Page,
117
+ state: 'load' | 'domcontentloaded' | 'networkidle' = 'load',
118
+ timeout: number = 30000,
119
+ ): Promise<void> {
120
+ await page.waitForLoadState(state, { timeout });
121
+ }
122
+
123
+ /**
124
+ * Wait for navigation to complete
125
+ */
126
+ static async waitForNavigation(
127
+ page: Page,
128
+ action: () => Promise<void>,
129
+ timeout: number = 30000,
130
+ ): Promise<void> {
131
+ await Promise.all([page.waitForNavigation({ timeout }), action()]);
132
+ }
133
+
134
+ /**
135
+ * Wait for selector with custom timeout
136
+ */
137
+ static async waitForSelector(
138
+ page: Page,
139
+ selector: string,
140
+ options?: {
141
+ timeout?: number;
142
+ state?: 'attached' | 'detached' | 'visible' | 'hidden';
143
+ },
144
+ ): Promise<void> {
145
+ await page.locator(selector).waitFor({
146
+ timeout: options?.timeout || 30000,
147
+ state: options?.state || 'visible',
148
+ });
149
+ }
150
+
151
+ /**
152
+ * Retry function with exponential backoff
153
+ */
154
+ static async retry<T>(
155
+ fn: () => Promise<T>,
156
+ options?: {
157
+ maxRetries?: number;
158
+ initialDelay?: number;
159
+ maxDelay?: number;
160
+ factor?: number;
161
+ },
162
+ ): Promise<T> {
163
+ const { maxRetries = 3, initialDelay = 1000, maxDelay = 10000, factor = 2 } = options || {};
164
+
165
+ let lastError: Error;
166
+ let delay = initialDelay;
167
+
168
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
169
+ try {
170
+ return await fn();
171
+ } catch (error) {
172
+ lastError = error as Error;
173
+ if (attempt < maxRetries) {
174
+ await this.wait(Math.min(delay, maxDelay));
175
+ delay *= factor;
176
+ }
177
+ }
178
+ }
179
+
180
+ throw lastError!;
181
+ }
182
+
183
+ /**
184
+ * Poll until condition is met or timeout
185
+ */
186
+ static async poll<T>(
187
+ fn: () => Promise<T | null | undefined>,
188
+ options?: {
189
+ timeout?: number;
190
+ interval?: number;
191
+ },
192
+ ): Promise<T> {
193
+ const timeout = options?.timeout || 30000;
194
+ const interval = options?.interval || 1000;
195
+ const startTime = Date.now();
196
+
197
+ while (Date.now() - startTime < timeout) {
198
+ const result = await fn();
199
+ if (result !== null && result !== undefined) {
200
+ return result;
201
+ }
202
+ await this.wait(interval);
203
+ }
204
+
205
+ throw new Error('Polling timed out');
206
+ }
207
+ }