Skip to content

Commit

Permalink
simplify the code ScrollScreenshot
Browse files Browse the repository at this point in the history
  • Loading branch information
ysmood committed Jul 6, 2024
1 parent be0491c commit e392af2
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 40 deletions.
4 changes: 2 additions & 2 deletions must.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,9 +387,9 @@ func (p *Page) MustScreenshotFullPage(toFile ...string) []byte {
return bin
}

// MustScrollScreenshotPage is similar to [Page.ScrollScreenshot].
// MustScrollScreenshot is similar to [Page.ScrollScreenshot].
// If the toFile is "", it Page.will save output to "tmp/screenshots" folder, time as the file name.
func (p *Page) MustScrollScreenshotPage(toFile ...string) []byte {
func (p *Page) MustScrollScreenshot(toFile ...string) []byte {
bin, err := p.ScrollScreenshot(nil)
p.e(err)
p.e(saveFile(saveFileTypeScreenshot, bin, toFile))
Expand Down
37 changes: 12 additions & 25 deletions page.go
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ type ScrollScreenshotOptions struct {
// but achieves it by scrolling and capturing screenshots in a loop, and then stitching them together.
// Note that this method also has a flaw: when there are elements with fixed
// positioning on the page (usually header navigation components),
// these elements will appear repeatedly, you can set the FixedTop parameter to optimize it.
// these elements will appear repeatedly, you can set the FixedTop parameter to optimize it.
//
// Only support png and jpeg format yet, webP is not supported because no suitable processing
// library was found in golang.
Expand Down Expand Up @@ -517,34 +517,20 @@ func (p *Page) ScrollScreenshot(opt *ScrollScreenshotOptions) ([]byte, error) {
var images []utils.ImgWithBox

for {
var clip *proto.PageViewport
clip := &proto.PageViewport{
X: 0,
Y: scrollTop,
Width: metrics.CSSVisualViewport.ClientWidth,
Scale: 1,
}

scrollY := viewpointHeight - (opt.FixedTop + opt.FixedBottom)
if scrollTop+viewpointHeight > contentHeight {
clip = &proto.PageViewport{
X: 0,
Y: scrollTop,
Width: metrics.CSSVisualViewport.ClientWidth,
Height: contentHeight - scrollTop,
Scale: 1,
}
clip.Height = contentHeight - scrollTop
} else {
if scrollTop == 0 {
clip = &proto.PageViewport{
X: 0,
Y: scrollTop,
Width: metrics.CSSVisualViewport.ClientWidth,
Height: scrollY,
Scale: 1,
}
} else {
clip = &proto.PageViewport{
X: 0,
Y: scrollTop + opt.FixedTop,
Width: metrics.CSSVisualViewport.ClientWidth,
Height: scrollY,
Scale: 1,
}
clip.Height = scrollY
if scrollTop != 0 {
clip.Y += opt.FixedTop
}
}

Expand All @@ -567,6 +553,7 @@ func (p *Page) ScrollScreenshot(opt *ScrollScreenshotOptions) ([]byte, error) {
if scrollTop >= contentHeight {
break
}

err = p.Mouse.Scroll(0, scrollY, 1)
if err != nil {
return nil, fmt.Errorf("scroll error: %w", err)
Expand Down
31 changes: 18 additions & 13 deletions page_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -777,12 +777,12 @@ func TestScreenshotFullPage(t *testing.T) {
})
}

func TestScrollScreenshotPage(t *testing.T) {
func TestScrollScreenshot(t *testing.T) {
g := setup(t)

p := g.page.MustNavigate(g.srcFile("fixtures/scroll-y.html"))
p.MustElement("button")
data := p.MustScrollScreenshotPage()
data := p.MustScrollScreenshot()
img, err := png.Decode(bytes.NewBuffer(data))
g.E(err)
res := p.MustEval(`() => ({w: document.documentElement.scrollWidth, h: document.documentElement.scrollHeight})`)
Expand All @@ -797,53 +797,58 @@ func TestScrollScreenshotPage(t *testing.T) {
g.Eq(1280, res.Get("w").Int())
g.Eq(800, res.Get("h").Int())

p.MustScrollScreenshotPage()
p.MustScrollScreenshot()

noEmulation := g.newPage(g.blank())
g.E(noEmulation.SetViewport(nil))
noEmulation.MustScrollScreenshotPage()
noEmulation.MustScrollScreenshot()
}

func TestScrollScreenshotErrors(t *testing.T) {
g := setup(t)
g.cancelTimeout()

p := g.page.MustNavigate(g.srcFile("fixtures/scroll-y.html"))

g.Panic(func() {
// mock error for get CSSContentSize
g.mc.stubErr(1, proto.PageGetLayoutMetrics{})
p.MustScrollScreenshotPage()
p.MustScrollScreenshot()
})
g.Panic(func() {
g.mc.stub(1, proto.PageGetLayoutMetrics{}, func(_ StubSend) (gson.JSON, error) {
return gson.New(proto.PageGetLayoutMetricsResult{
CSSVisualViewport: &proto.PageVisualViewport{},
}), nil
})
p.MustScrollScreenshotPage()
p.MustScrollScreenshot()
})
g.Panic(func() {
g.mc.stub(1, proto.PageGetLayoutMetrics{}, func(_ StubSend) (gson.JSON, error) {
return gson.New(proto.PageGetLayoutMetricsResult{
CSSContentSize: &proto.DOMRect{},
}), nil
})
p.MustScrollScreenshotPage()
p.MustScrollScreenshot()
})
g.Panic(func() {
// mock error for scroll
g.mc.stubErr(1, proto.InputDispatchMouseEvent{})
p.MustScrollScreenshotPage()
p.MustScrollScreenshot()
})

g.Panic(func() {
// mock error for Screenshot
g.mc.stubErr(1, proto.PageCaptureScreenshot{})
p.MustScrollScreenshotPage()
p.MustScrollScreenshot()
})

g.Panic(func() {
// mock error for WaitStable
g.mc.stubErr(1, proto.DOMSnapshotCaptureSnapshot{})
p.MustScrollScreenshotPage()
p.MustScrollScreenshot()
})

// test unsupported format
_, err = p.ScrollScreenshot(&rod.ScrollScreenshotOptions{
_, err := p.ScrollScreenshot(&rod.ScrollScreenshotOptions{
/* cspell: disable-next-line */
Format: proto.PageCaptureScreenshotFormatWebp,
Quality: gson.Int(10),
Expand Down

0 comments on commit e392af2

Please sign in to comment.