@@ -90,13 +90,13 @@ var defaultTargets = []Target{
90
90
// If no elements are found, an error is returned.
91
91
// If more than one element is found, one is chosen at random.
92
92
// The label of the clicked element is returned.
93
- func ClickRandomElement (ctx context.Context , randIntn func (int ) int ) (Label , Action , error ) {
93
+ func ClickRandomElement (ctx context.Context , log slog. Logger , randIntn func (int ) int , deadline time. Time ) (Label , Action , error ) {
94
94
var xpath Selector
95
95
var found bool
96
96
var err error
97
97
matches := make ([]Target , 0 )
98
98
for _ , tgt := range defaultTargets {
99
- xpath , found , err = randMatch (ctx , tgt .ClickOn , randIntn )
99
+ xpath , found , err = randMatch (ctx , log , tgt .ClickOn , randIntn , deadline )
100
100
if err != nil {
101
101
return "" , nil , xerrors .Errorf ("find matches for %q: %w" , tgt .ClickOn , err )
102
102
}
@@ -111,14 +111,20 @@ func ClickRandomElement(ctx context.Context, randIntn func(int) int) (Label, Act
111
111
}
112
112
113
113
if len (matches ) == 0 {
114
+ log .Debug (ctx , "no matches found this time" )
114
115
return "" , nil , xerrors .Errorf ("no matches found" )
115
116
}
116
117
match := pick (matches , randIntn )
117
- // rely on map iteration order being random
118
118
act := func (actx context.Context ) error {
119
- if err := clickAndWait (actx , match .ClickOn , match .WaitFor ); err != nil {
119
+ log .Debug (ctx , "clicking" , slog .F ("label" , match .Label ), slog .F ("xpath" , match .ClickOn ))
120
+ if err := runWithDeadline (ctx , deadline , chromedp .Click (match .ClickOn , chromedp .NodeReady )); err != nil {
121
+ log .Error (ctx , "click failed" , slog .F ("label" , match .Label ), slog .F ("xpath" , match .ClickOn ), slog .Error (err ))
120
122
return xerrors .Errorf ("click %q: %w" , match .ClickOn , err )
121
123
}
124
+ if err := runWithDeadline (ctx , deadline , chromedp .WaitReady (match .WaitFor )); err != nil {
125
+ log .Error (ctx , "wait failed" , slog .F ("label" , match .Label ), slog .F ("xpath" , match .WaitFor ), slog .Error (err ))
126
+ return xerrors .Errorf ("wait for %q: %w" , match .WaitFor , err )
127
+ }
122
128
return nil
123
129
}
124
130
return match .Label , act , nil
@@ -128,26 +134,32 @@ func ClickRandomElement(ctx context.Context, randIntn func(int) int) (Label, Act
128
134
// The returned selector is the full XPath of the matched node.
129
135
// If no matches are found, an error is returned.
130
136
// If multiple matches are found, one is chosen at random.
131
- func randMatch (ctx context.Context , s Selector , randIntn func (int ) int ) (Selector , bool , error ) {
137
+ func randMatch (ctx context.Context , log slog. Logger , s Selector , randIntn func (int ) int , deadline time. Time ) (Selector , bool , error ) {
132
138
var nodes []* cdp.Node
133
- err := chromedp .Run (ctx , chromedp .Nodes (s , & nodes , chromedp .NodeVisible , chromedp .AtLeast (0 )))
134
- if err != nil {
139
+ log .Debug (ctx , "getting nodes for selector" , slog .F ("selector" , s ))
140
+ if err := runWithDeadline (ctx , deadline , chromedp .Nodes (s , & nodes , chromedp .NodeReady , chromedp .AtLeast (0 ))); err != nil {
141
+ log .Debug (ctx , "failed to get nodes for selector" , slog .F ("selector" , s ), slog .Error (err ))
135
142
return "" , false , xerrors .Errorf ("get nodes for selector %q: %w" , s , err )
136
143
}
137
144
if len (nodes ) == 0 {
145
+ log .Debug (ctx , "no nodes found for selector" , slog .F ("selector" , s ))
138
146
return "" , false , nil
139
147
}
140
148
n := pick (nodes , randIntn )
149
+ log .Debug (ctx , "found node" , slog .F ("node" , n .FullXPath ()))
141
150
return Selector (n .FullXPath ()), true , nil
142
151
}
143
152
144
- // clickAndWait clicks the given selector and waits for the page to finish loading.
145
- // The page is considered loaded when the network event "LoadingFinished" is received.
146
- func clickAndWait (ctx context.Context , clickOn , waitFor Selector ) error {
147
- return chromedp .Run (ctx , chromedp.Tasks {
148
- chromedp .Click (clickOn , chromedp .NodeVisible ),
149
- chromedp .WaitVisible (waitFor , chromedp .NodeVisible ),
150
- })
153
+ func waitForWorkspacesPageLoaded (ctx context.Context , deadline time.Time ) error {
154
+ return runWithDeadline (ctx , deadline , chromedp .WaitReady (`tbody.MuiTableBody-root` ))
155
+ }
156
+
157
+ func runWithDeadline (ctx context.Context , deadline time.Time , acts ... chromedp.Action ) error {
158
+ deadlineCtx , deadlineCancel := context .WithDeadline (ctx , deadline )
159
+ defer deadlineCancel ()
160
+ c := chromedp .FromContext (ctx )
161
+ tasks := chromedp .Tasks (acts )
162
+ return tasks .Do (cdp .WithExecutor (deadlineCtx , c .Target ))
151
163
}
152
164
153
165
// initChromeDPCtx initializes a chromedp context with the given session token cookie
0 commit comments