Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.17.0] - 2025-12-15

### Added
- Support for multiple ReadySelectors

## [0.16.0] - 2025-12-15

### Added
Expand Down Expand Up @@ -110,6 +115,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Initial release

[0.17.0]: https://github.com/gooddata/gooddata-neobackstop/compare/v0.16.0...v0.17.0
[0.16.0]: https://github.com/gooddata/gooddata-neobackstop/compare/v0.15.0...v0.16.0
[0.15.0]: https://github.com/gooddata/gooddata-neobackstop/compare/v0.14.0...v0.15.0
[0.14.0]: https://github.com/gooddata/gooddata-neobackstop/compare/v0.13.0...v0.14.0
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.16.0
0.17.0
1 change: 1 addition & 0 deletions converters/converters.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ func scenarioToInternal(b browser.Browser, v viewport.Viewport, s scenario.Scena
Label: s.Label,
Url: s.Url,
ReadySelector: s.ReadySelector,
ReadySelectors: s.ReadySelectors,
Delay: s.Delay,
ReloadAfterReady: s.ReloadAfterReady,
KeyPressSelector: s.KeyPressSelector,
Expand Down
1 change: 1 addition & 0 deletions internals/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type Scenario struct {
Label string `json:"label"`
Url string `json:"url"`
ReadySelector *scenario.ReadySelector `json:"readySelector"`
ReadySelectors []scenario.ReadySelector `json:"readySelectors"`
ReloadAfterReady bool `json:"reloadAfterReady"`
Delay *scenario.Delay `json:"delay"`
KeyPressSelector *scenario.KeyPressSelector `json:"keyPressSelector"`
Expand Down
1 change: 1 addition & 0 deletions scenario/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ type Scenario struct {
Label string `json:"label"`
Url string `json:"url"`
ReadySelector *ReadySelector `json:"readySelector"`
ReadySelectors []ReadySelector `json:"readySelectors"`
ReloadAfterReady bool `json:"reloadAfterReady"`
Delay *Delay `json:"delay"`
KeyPressSelector *KeyPressSelector `json:"keyPressSelector"`
Expand Down
8 changes: 8 additions & 0 deletions screenshotter/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ func Job(logPrefix string, saveDir string, viewportLabel string, page playwright
return
}

// readySelectors
sErr = operations.ReadySelectors(page, job.ReadySelectors)
if sErr != nil {
fmt.Println(logPrefix, *sErr+", exiting quietly without a screenshot")
results <- buildResultFromScenario(job, nil, sErr)
return
}

// reloadAfterReady
sErr = operations.ReloadAfterReady(page, job)
if sErr != nil {
Expand Down
47 changes: 47 additions & 0 deletions screenshotter/operations/readySelectors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package operations

import (
"strconv"

"github.com/gooddata/gooddata-neobackstop/scenario"
"github.com/playwright-community/playwright-go"
)

func ReadySelectors(page playwright.Page, selectors []scenario.ReadySelector) *string {
if len(selectors) == 0 {
return nil
}

maxAttempts := 6
timeout := float64(5000) // 5 seconds

for attempt := 0; attempt < maxAttempts; attempt++ {
allPresent := true
var failedSelector string

for _, sel := range selectors {
state := playwright.WaitForSelectorState(sel.State)
_, err := page.WaitForSelector(sel.Selector, playwright.PageWaitForSelectorOptions{
State: &state,
Timeout: playwright.Float(timeout),
})
if err != nil {
allPresent = false
failedSelector = sel.Selector
break // restart from first selector
}
}

if allPresent {
return nil // all selectors present in same pass
}

// last attempt failed
if attempt == maxAttempts-1 {
e := "ReadySelector " + failedSelector + " didn't appear after " + strconv.Itoa(maxAttempts) + " attempts"
return &e
}
}

return nil
}