1
1
import path from "node:path" ;
2
- import { expect , test } from "@playwright/test" ;
2
+ import { type Locator , expect , test } from "@playwright/test" ;
3
3
import {
4
4
currentUser ,
5
5
importTemplate ,
@@ -14,18 +14,22 @@ test.beforeEach(async ({ page }) => {
14
14
await login ( page ) ;
15
15
} ) ;
16
16
17
+ const waitForBuildTimeout = 120_000 ; // Builds can take a while, let's give them at most 2m.
18
+
19
+ const templateFiles = [
20
+ path . join ( __dirname , "basic-presets-with-prebuild/main.tf" ) ,
21
+ path . join ( __dirname , "basic-presets-with-prebuild/.terraform.lock.hcl" ) ,
22
+ ] ;
23
+
24
+ const expectedPrebuilds = 2 ;
25
+
17
26
// NOTE: requires the `workspace-prebuilds` experiment enabled!
18
27
test ( "create template with desired prebuilds" , async ( { page, baseURL } ) => {
19
28
requiresLicense ( ) ;
20
29
21
- const expectedPrebuilds = 2 ;
22
-
23
30
// Create new template.
24
31
const templateName = randomName ( ) ;
25
- await importTemplate ( page , templateName , [
26
- path . join ( __dirname , "basic-presets-with-prebuild/main.tf" ) ,
27
- path . join ( __dirname , "basic-presets-with-prebuild/.terraform.lock.hcl" ) ,
28
- ] ) ;
32
+ await importTemplate ( page , templateName , templateFiles ) ;
29
33
30
34
await page . goto (
31
35
`/workspaces?filter=owner:prebuilds%20template:${ templateName } &page=1` ,
@@ -34,13 +38,13 @@ test("create template with desired prebuilds", async ({ page, baseURL }) => {
34
38
35
39
// Wait for prebuilds to show up.
36
40
const prebuilds = page . getByTestId ( / ^ w o r k s p a c e - .+ $ / ) ;
37
- await prebuilds . first ( ) . waitFor ( { state : "visible" , timeout : 120_000 } ) ;
38
- expect ( ( await prebuilds . all ( ) ) . length ) . toEqual ( expectedPrebuilds ) ;
41
+ await waitForExpectedCount ( prebuilds , expectedPrebuilds ) ;
39
42
40
43
// Wait for prebuilds to start.
41
- const runningPrebuilds = page . getByTestId ( "build-status" ) . getByText ( "Running" ) ;
42
- await runningPrebuilds . first ( ) . waitFor ( { state : "visible" , timeout : 120_000 } ) ;
43
- expect ( ( await runningPrebuilds . all ( ) ) . length ) . toEqual ( expectedPrebuilds ) ;
44
+ const runningPrebuilds = page
45
+ . getByTestId ( "build-status" )
46
+ . getByText ( "Running" ) ;
47
+ await waitForExpectedCount ( runningPrebuilds , expectedPrebuilds ) ;
44
48
} ) ;
45
49
46
50
// NOTE: requires the `workspace-prebuilds` experiment enabled!
@@ -51,10 +55,7 @@ test("claim prebuild matching selected preset", async ({ page, baseURL }) => {
51
55
52
56
// Create new template.
53
57
const templateName = randomName ( ) ;
54
- await importTemplate ( page , templateName , [
55
- path . join ( __dirname , "basic-presets-with-prebuild/main.tf" ) ,
56
- path . join ( __dirname , "basic-presets-with-prebuild/.terraform.lock.hcl" ) ,
57
- ] ) ;
58
+ await importTemplate ( page , templateName , templateFiles ) ;
58
59
59
60
await page . goto (
60
61
`/workspaces?filter=owner:prebuilds%20template:${ templateName } &page=1` ,
@@ -63,11 +64,17 @@ test("claim prebuild matching selected preset", async ({ page, baseURL }) => {
63
64
64
65
// Wait for prebuilds to show up.
65
66
const prebuilds = page . getByTestId ( / ^ w o r k s p a c e - .+ $ / ) ;
66
- await prebuilds . first ( ) . waitFor ( { state : "visible" , timeout : 120_000 } ) ;
67
+ await waitForExpectedCount ( prebuilds , expectedPrebuilds ) ;
68
+
69
+ const previousWorkspaceNames = await Promise . all (
70
+ ( await prebuilds . all ( ) ) . map ( ( value ) => {
71
+ return value . getByText ( / p r e b u i l d - .+ / ) . textContent ( ) ;
72
+ } ) ,
73
+ ) ;
67
74
68
75
// Wait for prebuilds to start.
69
- const runningPrebuilds = page . getByTestId ( "build-status" ) . getByText ( "Running" ) ;
70
- await runningPrebuilds . first ( ) . waitFor ( { state : "visible" , timeout : 120_000 } ) ;
76
+ let runningPrebuilds = page . getByTestId ( "build-status" ) . getByText ( "Running" ) ;
77
+ await waitForExpectedCount ( runningPrebuilds , expectedPrebuilds ) ;
71
78
72
79
// Open the first prebuild.
73
80
await runningPrebuilds . first ( ) . click ( ) ;
@@ -101,12 +108,49 @@ test("claim prebuild matching selected preset", async ({ page, baseURL }) => {
101
108
// Wait for the workspace build display to be navigated to.
102
109
const user = currentUser ( page ) ;
103
110
await page . waitForURL ( `/@${ user . username } /${ workspaceName } ` , {
104
- timeout : 120_000 , // Account for workspace build time.
111
+ timeout : waitForBuildTimeout , // Account for workspace build time.
105
112
} ) ;
106
113
107
114
// Validate the workspace metadata that it was indeed a claimed prebuild.
108
115
const indicator = page . getByText ( "Was Prebuild" ) ;
109
116
await indicator . waitFor ( { timeout : 60_000 } ) ;
110
117
const text = indicator . locator ( "xpath=.." ) . getByText ( "Yes" ) ;
111
118
await text . waitFor ( { timeout : 30_000 } ) ;
119
+
120
+ // Navigate back to prebuilds page to see that a new prebuild replaced the claimed one.
121
+ await page . goto (
122
+ `/workspaces?filter=owner:prebuilds%20template:${ templateName } &page=1` ,
123
+ { waitUntil : "domcontentloaded" } ,
124
+ ) ;
125
+
126
+ // Wait for prebuilds to show up.
127
+ const newPrebuilds = page . getByTestId ( / ^ w o r k s p a c e - .+ $ / ) ;
128
+ await waitForExpectedCount ( newPrebuilds , expectedPrebuilds ) ;
129
+
130
+ const currentWorkspaceNames = await Promise . all (
131
+ ( await newPrebuilds . all ( ) ) . map ( ( value ) => {
132
+ return value . getByText ( / p r e b u i l d - .+ / ) . textContent ( ) ;
133
+ } ) ,
134
+ ) ;
135
+
136
+ // Ensure the prebuilds have changed.
137
+ expect ( currentWorkspaceNames ) . not . toEqual ( previousWorkspaceNames ) ;
138
+
139
+ // Wait for prebuilds to start.
140
+ runningPrebuilds = page . getByTestId ( "build-status" ) . getByText ( "Running" ) ;
141
+ await waitForExpectedCount ( runningPrebuilds , expectedPrebuilds ) ;
112
142
} ) ;
143
+
144
+ function waitForExpectedCount ( prebuilds : Locator , expectedCount : number ) {
145
+ return expect
146
+ . poll (
147
+ async ( ) => {
148
+ return ( await prebuilds . all ( ) ) . length === expectedCount ;
149
+ } ,
150
+ {
151
+ intervals : [ 100 ] ,
152
+ timeout : waitForBuildTimeout ,
153
+ } ,
154
+ )
155
+ . toBe ( true ) ;
156
+ }
0 commit comments