1
- import { test , expect } from '@playwright/test' ;
2
- import { BasePage } from './utils/base-test' ;
3
- import { selectors } from './utils/selectors' ;
4
- import { Constants } from './utils/constants' ;
1
+ import { test , expect , Page } from '@playwright/test' ;
2
+
3
+ // Helper functions
4
+ async function openLocalhost ( page : Page , port : number ) {
5
+ await page . goto ( `http://localhost:${ port } ` ) ;
6
+ await page . waitForLoadState ( 'networkidle' ) ;
7
+ }
8
+
9
+ async function checkElementWithTextPresence ( page : Page , selector : string , text : string , timeout : number = 10000 ) {
10
+ await page . locator ( selector ) . filter ( { hasText : text } ) . waitFor ( { timeout } ) ;
11
+ }
12
+
13
+ async function checkElementVisibility ( page : Page , selector : string , timeout : number = 10000 ) {
14
+ await page . locator ( selector ) . waitFor ( { state : 'visible' , timeout } ) ;
15
+ }
16
+
17
+ async function checkElementBackgroundColor ( page : Page , selector : string , expectedColor : string ) {
18
+ const element = page . locator ( selector ) ;
19
+ await element . waitFor ( { state : 'visible' } ) ;
20
+ const backgroundColor = await element . evaluate ( ( el ) => {
21
+ return window . getComputedStyle ( el ) . backgroundColor ;
22
+ } ) ;
23
+ if ( backgroundColor !== expectedColor ) {
24
+ throw new Error ( `Expected background color ${ expectedColor } , but got ${ backgroundColor } ` ) ;
25
+ }
26
+ }
27
+
28
+ async function clickElementWithText ( page : Page , selector : string , text : string ) {
29
+ await page . locator ( selector ) . filter ( { hasText : text } ) . click ( ) ;
30
+ }
31
+
32
+ async function waitForDynamicImport ( page : Page , timeout : number = 5000 ) {
33
+ // Wait for any dynamic imports to complete
34
+ await page . waitForTimeout ( 1000 ) ;
35
+ await page . waitForLoadState ( 'networkidle' , { timeout } ) ;
36
+ }
37
+
38
+ async function checkDateFormat ( page : Page ) {
39
+ // Check for moment.js formatted date (MMMM Do YYYY, h:mm format)
40
+ const dateElement = page . locator ( 'text=/[A-Z][a-z]+ \\\\d{1,2}[a-z]{2} \\\\d{4}, \\\\d{1,2}:\\\\d{2}/' ) ;
41
+ await dateElement . waitFor ( { timeout : 5000 } ) ;
42
+ }
5
43
6
44
const appsData = [
7
45
{
8
- headerSelector : selectors . tags . headers . h1 ,
9
- subHeaderSelector : selectors . tags . headers . h2 ,
10
- headerText : Constants . elementsText . dynamicRemotesApp . header ,
11
- appNameText : Constants . commonConstantsData . commonCountAppNames . app1 ,
12
- widgetName : Constants . elementsText . dynamicRemotesApp . synchronousImportWidgetsNames ,
13
- widgetParagraph : Constants . commonPhrases . dynamicRemotesApp . widgetParagraphText ,
14
- widgetColor : Constants . color . dynamicRemotesWidgetColor ,
46
+ headerSelector : 'h1' ,
47
+ subHeaderSelector : 'h2' ,
48
+ headerText : '🌐 Dynamic System Host' ,
49
+ appNameText : 'App 1 - Demonstrating Synchronous Imports with Dynamic Remotes' ,
50
+ widgetName : [ 'App 1 Widget' , 'App 2 Widget' ] ,
51
+ widgetParagraph : [ "Moment shouldn't download twice" , "Moment shouldn't download twice" ] ,
52
+ widgetColor : [ 'rgb(255, 0, 0)' , 'rgb(0, 0, 255)' ] ,
15
53
widgetIndexNumber : 1 ,
16
54
isTwoWidgets : true ,
17
55
host : 3001 ,
18
56
} ,
19
57
{
20
- headerSelector : selectors . tags . headers . h1 ,
21
- subHeaderSelector : selectors . tags . headers . h2 ,
22
- headerText : Constants . elementsText . dynamicRemotesApp . header ,
23
- appNameText : Constants . commonConstantsData . commonCountAppNames . app2 ,
24
- widgetName : Constants . elementsText . dynamicRemotesApp . synchronousImportWidgetsNames ,
25
- widgetParagraph : Constants . commonPhrases . dynamicRemotesApp . widgetParagraphText ,
26
- widgetColor : Constants . color . dynamicRemotesWidgetColor ,
58
+ headerSelector : 'h1' ,
59
+ subHeaderSelector : 'h2' ,
60
+ headerText : '🌐 Dynamic System Host' ,
61
+ appNameText : 'App 2' ,
62
+ widgetName : [ 'App 1 Widget' , 'App 2 Widget' ] ,
63
+ widgetParagraph : [ "Moment shouldn't download twice" , "Moment shouldn't download twice" ] ,
64
+ widgetColor : [ 'rgb(255, 0, 0)' , 'rgb(0, 0, 255)' ] ,
27
65
widgetIndexNumber : 2 ,
28
66
isTwoWidgets : false ,
29
67
host : 3002 ,
@@ -37,22 +75,23 @@ test.describe('Dynamic Remotes Synchronous Imports E2E Tests', () => {
37
75
38
76
test . describe ( `Check ${ appNameText } ` , ( ) => {
39
77
test ( `should display ${ appNameText } elements correctly` , async ( { page } ) => {
40
- const basePage = new BasePage ( page ) ;
41
78
const consoleErrors : string [ ] = [ ] ;
42
- basePage . page . on ( 'console' , ( msg ) => {
79
+ page . on ( 'console' , ( msg ) => {
43
80
if ( msg . type ( ) === 'error' ) {
44
81
consoleErrors . push ( msg . text ( ) ) ;
45
82
}
46
83
} ) ;
47
84
48
- await basePage . openLocalhost ( host ) ;
85
+ await openLocalhost ( page , host ) ;
49
86
50
87
// Check header and subheader exist
51
- await basePage . checkElementWithTextPresence (
88
+ await checkElementWithTextPresence (
89
+ page ,
52
90
appData . headerSelector ,
53
91
headerText
54
92
) ;
55
- await basePage . checkElementWithTextPresence (
93
+ await checkElementWithTextPresence (
94
+ page ,
56
95
appData . subHeaderSelector ,
57
96
appNameText
58
97
) ;
@@ -68,59 +107,62 @@ test.describe('Dynamic Remotes Synchronous Imports E2E Tests', () => {
68
107
} ) ;
69
108
70
109
test ( `should display widgets correctly in ${ appNameText } ` , async ( { page } ) => {
71
- const basePage = new BasePage ( page ) ;
72
- await basePage . openLocalhost ( host ) ;
110
+ await openLocalhost ( page , host ) ;
73
111
74
112
if ( isTwoWidgets ) {
75
113
// App 1 has two widgets (local + remote)
76
114
for ( let i = 0 ; i < widgetName . length ; i ++ ) {
77
- const widgetSelector = i === 0 ? selectors . dataTestIds . app1Widget : selectors . dataTestIds . app2Widget ;
115
+ const widgetSelector = i === 0 ? '[data-e2e="WIDGET__1"]' : '[data-e2e="WIDGET__2"]' ;
78
116
79
117
// Check widget visibility
80
- await basePage . checkElementVisibility ( widgetSelector ) ;
118
+ await checkElementVisibility ( page , widgetSelector ) ;
81
119
82
120
// Check widget title
83
- await basePage . checkElementWithTextPresence (
121
+ await checkElementWithTextPresence (
122
+ page ,
84
123
appData . subHeaderSelector ,
85
124
widgetName [ i ]
86
125
) ;
87
126
88
127
// Check widget paragraph text
89
- await basePage . checkElementWithTextPresence (
90
- selectors . tags . paragraph ,
128
+ await checkElementWithTextPresence (
129
+ page ,
130
+ 'p' ,
91
131
widgetParagraph [ i ]
92
132
) ;
93
133
94
134
// Check moment.js date formatting
95
- await basePage . checkDateFormat ( ) ;
135
+ await checkDateFormat ( page ) ;
96
136
97
137
// Check widget background color
98
- await basePage . checkElementBackgroundColor ( widgetSelector , widgetColor [ i ] ) ;
138
+ await checkElementBackgroundColor ( page , widgetSelector , widgetColor [ i ] ) ;
99
139
}
100
140
} else {
101
141
// App 2 has one widget
102
- const widgetSelector = selectors . dataTestIds . app2Widget ;
142
+ const widgetSelector = '[data-e2e="WIDGET__2"]' ;
103
143
104
144
// Check widget visibility
105
- await basePage . checkElementVisibility ( widgetSelector ) ;
145
+ await checkElementVisibility ( page , widgetSelector ) ;
106
146
107
147
// Check widget title
108
- await basePage . checkElementWithTextPresence (
148
+ await checkElementWithTextPresence (
149
+ page ,
109
150
appData . subHeaderSelector ,
110
151
widgetName [ widgetIndexNumber - 1 ]
111
152
) ;
112
153
113
154
// Check widget paragraph text
114
- await basePage . checkElementWithTextPresence (
115
- selectors . tags . paragraph ,
155
+ await checkElementWithTextPresence (
156
+ page ,
157
+ 'p' ,
116
158
widgetParagraph [ widgetIndexNumber - 1 ]
117
159
) ;
118
160
119
161
// Check moment.js date formatting
120
- await basePage . checkDateFormat ( ) ;
162
+ await checkDateFormat ( page ) ;
121
163
122
164
// Check widget background color
123
- await basePage . checkElementBackgroundColor ( widgetSelector , widgetColor [ 1 ] ) ;
165
+ await checkElementBackgroundColor ( page , widgetSelector , widgetColor [ 1 ] ) ;
124
166
}
125
167
} ) ;
126
168
} ) ;
@@ -158,7 +200,7 @@ test.describe('Dynamic Remotes Synchronous Imports E2E Tests', () => {
158
200
await page . waitForLoadState ( 'networkidle' ) ;
159
201
160
202
// Check that App 2 widget is loaded synchronously (no dynamic import button clicks)
161
- await page . waitForSelector ( selectors . dataTestIds . app2Widget , { timeout : 10000 } ) ;
203
+ await page . waitForSelector ( '[data-e2e="WIDGET__2"]' , { timeout : 10000 } ) ;
162
204
163
205
// Verify the remote entry was loaded
164
206
const remoteEntryRequests = networkRequests . filter ( url =>
@@ -179,8 +221,8 @@ test.describe('Dynamic Remotes Synchronous Imports E2E Tests', () => {
179
221
await page . waitForLoadState ( 'networkidle' ) ;
180
222
181
223
// Verify both widgets are present (demonstrating successful remote loading)
182
- await page . waitForSelector ( selectors . dataTestIds . app1Widget ) ;
183
- await page . waitForSelector ( selectors . dataTestIds . app2Widget ) ;
224
+ await page . waitForSelector ( '[data-e2e="WIDGET__1"]' ) ;
225
+ await page . waitForSelector ( '[data-e2e="WIDGET__2"]' ) ;
184
226
185
227
// Check that runtime plugin logged URL processing
186
228
const urlResolutionLogs = consoleMessages . filter ( msg =>
@@ -234,11 +276,10 @@ test.describe('Dynamic Remotes Synchronous Imports E2E Tests', () => {
234
276
} ) ;
235
277
236
278
test ( 'should demonstrate moment.js sharing' , async ( { page } ) => {
237
- const basePage = new BasePage ( page ) ;
238
- await basePage . openLocalhost ( 3001 ) ;
279
+ await openLocalhost ( page , 3001 ) ;
239
280
240
281
// Check that moment.js date is formatted correctly in both widgets
241
- const dateElements = basePage . page . locator ( 'text=/[A-Z][a-z]+ \\d{1,2}[a-z]{2} \\d{4}, \\d{1,2}:\\d{2}/' ) ;
282
+ const dateElements = page . locator ( 'text=/[A-Z][a-z]+ \\d{1,2}[a-z]{2} \\d{4}, \\d{1,2}:\\d{2}/' ) ;
242
283
243
284
// Should have date formatting in both local and remote widgets
244
285
await expect ( dateElements ) . toHaveCount ( 2 ) ;
@@ -276,8 +317,8 @@ test.describe('Dynamic Remotes Synchronous Imports E2E Tests', () => {
276
317
await page . waitForSelector ( 'h2:has-text("App 1")' ) ;
277
318
278
319
// Verify both widgets loaded successfully
279
- await page . waitForSelector ( selectors . dataTestIds . app1Widget ) ;
280
- await page . waitForSelector ( selectors . dataTestIds . app2Widget ) ;
320
+ await page . waitForSelector ( '[data-e2e="WIDGET__1"]' ) ;
321
+ await page . waitForSelector ( '[data-e2e="WIDGET__2"]' ) ;
281
322
} ) ;
282
323
} ) ;
283
324
} ) ;
0 commit comments