@@ -12,169 +12,71 @@ limitations under the License.
12
12
*/
13
13
14
14
import { test , expect } from '@playwright/test' ;
15
- import { setupDashboardAuthentication , generateTestDeploymentYaml } from './test-utils' ;
15
+ import { setupDashboardAuthentication , generateTestDeploymentYaml , createK8sDeployment , getDeploymentNameFromYaml } from './test-utils' ;
16
16
17
17
test . beforeEach ( async ( { page } ) => {
18
18
await setupDashboardAuthentication ( page ) ;
19
19
} ) ;
20
20
21
21
test ( 'should delete deployment successfully' , async ( { page } ) => {
22
+ // Create a test deployment directly via kubectl to set up test data
23
+ const testDeploymentYaml = generateTestDeploymentYaml ( ) ;
24
+ const deploymentName = getDeploymentNameFromYaml ( testDeploymentYaml ) ;
25
+
26
+ // Setup: Create deployment using kubectl
27
+ await createK8sDeployment ( testDeploymentYaml ) ;
28
+
22
29
// Navigate to workload page
23
30
await page . click ( 'text=Workloads' ) ;
24
31
await expect ( page . getByRole ( 'radio' , { name : 'Deployment' } ) ) . toBeChecked ( ) ;
25
32
await expect ( page . locator ( 'table' ) ) . toBeVisible ( { timeout : 30000 } ) ;
26
-
27
- // Create a test deployment
28
- await page . click ( 'button:has-text("Add")' ) ;
29
- await page . waitForSelector ( '[role="dialog"]' , { timeout : 10000 } ) ;
30
-
31
- // Listen for API calls
32
- const apiRequestPromise = page . waitForResponse ( response => {
33
- return response . url ( ) . includes ( '/api/v1/_raw/Deployment' ) && response . status ( ) === 200 ;
34
- } , { timeout : 15000 } ) ;
35
-
36
- const testDeploymentYaml = generateTestDeploymentYaml ( ) ;
37
-
38
- // Set Monaco editor DOM content
39
- await page . evaluate ( ( yaml ) => {
40
- const textarea = document . querySelector ( '.monaco-editor textarea' ) as HTMLTextAreaElement ;
41
- if ( textarea ) {
42
- textarea . value = yaml ;
43
- textarea . focus ( ) ;
44
- }
45
- } , testDeploymentYaml ) ;
46
-
47
- // Call React onChange callback to update component state
48
- await page . evaluate ( ( yaml ) => {
49
- const findReactFiber = ( element : any ) => {
50
- const keys = Object . keys ( element ) ;
51
- return keys . find ( key => key . startsWith ( '__reactFiber' ) || key . startsWith ( '__reactInternalInstance' ) ) ;
52
- } ;
53
-
54
- const monacoContainer = document . querySelector ( '.monaco-editor' ) ;
55
- if ( monacoContainer ) {
56
- const fiberKey = findReactFiber ( monacoContainer ) ;
57
- if ( fiberKey ) {
58
- let fiber = ( monacoContainer as any ) [ fiberKey ] ;
59
-
60
- while ( fiber ) {
61
- if ( fiber . memoizedProps && fiber . memoizedProps . onChange ) {
62
- fiber . memoizedProps . onChange ( yaml ) ;
63
- return ;
64
- }
65
- fiber = fiber . return ;
66
- }
67
- }
68
- }
69
33
70
- const dialog = document . querySelector ( '[role="dialog"]' ) ;
71
- if ( dialog ) {
72
- const fiberKey = findReactFiber ( dialog ) ;
73
- if ( fiberKey ) {
74
- let fiber = ( dialog as any ) [ fiberKey ] ;
75
-
76
- const traverse = ( node : any , depth = 0 ) => {
77
- if ( ! node || depth > 20 ) return false ;
78
-
79
- if ( node . memoizedProps && node . memoizedProps . onChange ) {
80
- node . memoizedProps . onChange ( yaml ) ;
81
- return true ;
82
- }
83
-
84
- if ( node . child && traverse ( node . child , depth + 1 ) ) return true ;
85
- if ( node . sibling && traverse ( node . sibling , depth + 1 ) ) return true ;
86
-
87
- return false ;
88
- } ;
89
-
90
- traverse ( fiber ) ;
91
- }
92
- }
93
- } , testDeploymentYaml ) ;
94
-
95
- // Wait for submit button to become enabled
96
- await expect ( page . locator ( '[role="dialog"] button:has-text("Submit")' ) ) . toBeEnabled ( ) ;
97
- await page . click ( '[role="dialog"] button:has-text("Submit")' ) ;
98
-
99
- // Wait for API call to succeed
100
- const response = await apiRequestPromise ;
101
- expect ( response . status ( ) ) . toBe ( 200 ) ;
102
-
103
- // Get the created deployment name
104
- const deploymentName = testDeploymentYaml . match ( / n a m e : ( .+ ) / ) ?. [ 1 ] ;
105
- if ( ! deploymentName ) {
106
- throw new Error ( 'Could not extract deployment name from YAML' ) ;
107
- }
108
-
109
- // Wait for success message to appear
110
- try {
111
- await expect ( page . locator ( 'text=Workloads Newly Added Success' ) ) . toBeVisible ( { timeout : 5000 } ) ;
112
- } catch ( e ) {
113
- // Success message may not appear, continue execution
114
- }
115
-
116
- // Wait for dialog to close
117
- await page . waitForSelector ( '[role="dialog"]' , { state : 'detached' , timeout : 10000 } ) . catch ( ( ) => { } ) ;
118
-
119
34
// Wait for deployment to appear in list
120
35
const table = page . locator ( 'table' ) ;
121
- await expect ( table ) . toBeVisible ( { timeout : 30000 } ) ;
122
-
123
- // Try multiple times to find deployment with more flexible selector
124
- let deploymentFound = false ;
125
- for ( let i = 0 ; i < 10 ; i ++ ) {
126
- try {
127
- const deploymentElement = page . locator ( `table tbody tr:has-text("${ deploymentName } ")` ) ;
128
- await expect ( deploymentElement ) . toBeVisible ( { timeout : 3000 } ) ;
129
- deploymentFound = true ;
130
- break ;
131
- } catch ( e ) {
132
- await page . waitForTimeout ( 2000 ) ; // Wait 2 seconds then retry
133
- }
134
- }
135
-
136
- if ( ! deploymentFound ) {
137
- throw new Error ( `Deployment ${ deploymentName } not found in the table after multiple attempts` ) ;
138
- }
139
-
36
+ await expect ( table . locator ( `text=${ deploymentName } ` ) ) . toBeVisible ( { timeout : 30000 } ) ;
37
+
140
38
// Find row containing test deployment name
141
39
const targetRow = page . locator ( `table tbody tr:has-text("${ deploymentName } ")` ) ;
142
40
await expect ( targetRow ) . toBeVisible ( { timeout : 15000 } ) ;
143
-
41
+
144
42
// Find Delete button in that row and click
145
- const deleteButton = targetRow . locator ( 'button[type="button"]' ) . filter ( { hasText : / ^ ( 删 除 | D e l e t e ) $ / } ) ;
43
+ const deleteButton = targetRow . locator ( 'button[type="button"]' ) . filter ( { hasText : / ^ ( D e l e t e ) $ / } ) ;
146
44
await expect ( deleteButton ) . toBeVisible ( { timeout : 10000 } ) ;
147
-
45
+
148
46
// Listen for delete API call
149
47
const deleteApiPromise = page . waitForResponse ( response => {
150
- return response . url ( ) . includes ( '/_raw/deployment' ) &&
151
- response . url ( ) . includes ( `name/${ deploymentName } ` ) &&
152
- response . request ( ) . method ( ) === 'DELETE' &&
153
- response . status ( ) === 200 ;
48
+ return response . url ( ) . includes ( '/_raw/deployment' ) &&
49
+ response . url ( ) . includes ( `name/${ deploymentName } ` ) &&
50
+ response . request ( ) . method ( ) === 'DELETE' &&
51
+ response . status ( ) === 200 ;
154
52
} , { timeout : 15000 } ) ;
155
-
53
+
156
54
await deleteButton . click ( ) ;
157
-
55
+
158
56
// Wait for delete confirmation tooltip to appear
159
57
await page . waitForSelector ( '[role="tooltip"]' , { timeout : 10000 } ) ;
160
-
58
+
161
59
// Click Confirm button to confirm deletion
162
60
const confirmButton = page . locator ( '[role="tooltip"] button' ) . filter ( { hasText : / ^ ( C o n f i r m ) $ / } ) ;
163
61
await expect ( confirmButton ) . toBeVisible ( { timeout : 5000 } ) ;
164
62
await confirmButton . click ( ) ;
165
-
63
+
166
64
// Wait for delete API call to succeed
167
- const deleteResponse = await deleteApiPromise ;
168
- expect ( deleteResponse . status ( ) ) . toBe ( 200 ) ;
169
-
65
+ await deleteApiPromise ;
66
+
170
67
// Wait for tooltip to close
171
68
await page . waitForSelector ( '[role="tooltip"]' , { state : 'detached' , timeout : 10000 } ) . catch ( ( ) => { } ) ;
172
69
70
+ // Refresh page to ensure UI is updated after deletion
71
+ await page . reload ( ) ;
72
+ await page . click ( 'text=Workloads' ) ;
73
+ await expect ( table ) . toBeVisible ( { timeout : 30000 } ) ;
74
+
173
75
// Verify deployment no longer exists in table
174
- await expect ( table . locator ( `text=${ deploymentName } ` ) ) . toHaveCount ( 0 , { timeout : 10000 } ) ;
76
+ await expect ( table . locator ( `text=${ deploymentName } ` ) ) . toHaveCount ( 0 , { timeout : 30000 } ) ;
175
77
176
78
// Debug
177
79
if ( process . env . DEBUG === 'true' ) {
178
- await page . screenshot ( { path : 'debug-deployment-delete.png' , fullPage : true } ) ;
80
+ await page . screenshot ( { path : 'debug-deployment-delete-kubectl .png' , fullPage : true } ) ;
179
81
}
180
- } ) ;
82
+ } ) ;
0 commit comments