From c4efaffc1dd15cca7e9636e790aaeba02aab0621 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Thu, 2 Apr 2026 19:40:03 -0700 Subject: [PATCH 1/2] Try to make heading-nav-collapsed test more reliable This test seems to be a little flaky. This tries to make it more reliable by using `wait-for-` commands instead of `assert-`. My guess is that clicking on an element doesn't necessarily wait for all the javascript code to finish and the DOM to be done updating. --- tests/gui/heading-nav-collapsed.goml | 51 ++++++++++++++-------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/tests/gui/heading-nav-collapsed.goml b/tests/gui/heading-nav-collapsed.goml index b64d1174..efc9bce5 100644 --- a/tests/gui/heading-nav-collapsed.goml +++ b/tests/gui/heading-nav-collapsed.goml @@ -9,38 +9,39 @@ assert-text: (".current-header", "Heading 1") // Collapsed elements do not have "expanded" class. assert-attribute: ("li:has(> span > a[href='#heading-12'])", {"class": "header-item"}) assert-attribute: ("li:has(> span > a[href='#heading-21'])", {"class": "header-item"}) +assert-css: ("//a[@href='#heading-12']/../following-sibling::ol", {"display": "none"}) +assert-css: ("//a[@href='#heading-21']/../following-sibling::ol", {"display": "none"}) assert-property: ("div.on-this-page", {"innerHTML": '
  1. Heading 1
    1. Heading 1.1
    2. Heading 1.2
      1. Heading 1.2.1
      2. Heading 1.2.2
    3. Heading 1.3
  2. Heading 2
    1. Heading 2.1
      1. Heading 2.1.1
        1. Heading 2.1.1.1
          1. Heading 2.1.1.1.1
'}) // Click 1.2, expands it. click: "a.header-in-summary[href='#heading-12']" -assert-attribute: ("li:has(> span > a[href='#heading-12'])", {"class": "header-item expanded"}) -assert-attribute: ("li:has(> span > a[href='#heading-21'])", {"class": "header-item"}) -assert-css: ("//a[@href='#heading-12']/../following-sibling::ol", {"display": "block"}) +wait-for-attribute: ("li:has(> span > a[href='#heading-12'])", {"class": "header-item expanded"}) +wait-for-attribute: ("li:has(> span > a[href='#heading-21'])", {"class": "header-item"}) +wait-for-css: ("//a[@href='#heading-12']/../following-sibling::ol", {"display": "block"}) // Click 1.1, should collapse it. click: "a.header-in-summary[href='#heading-11']" -assert-attribute: ("li:has(> span > a[href='#heading-12'])", {"class": "header-item"}) -assert-attribute: ("li:has(> span > a[href='#heading-21'])", {"class": "header-item"}) -assert-css: ("//a[@href='#heading-12']/../following-sibling::ol", {"display": "none"}) +wait-for-attribute: ("li:has(> span > a[href='#heading-12'])", {"class": "header-item"}) +wait-for-attribute: ("li:has(> span > a[href='#heading-21'])", {"class": "header-item"}) +wait-for-css: ("//a[@href='#heading-12']/../following-sibling::ol", {"display": "none"}) // Click the chevron, should expand it. click: "a.header-in-summary[href='#heading-12'] ~ a.header-toggle" -assert-attribute: ("li:has(> span > a[href='#heading-12'])", {"class": "header-item expanded"}) -assert-attribute: ("li:has(> span > a[href='#heading-21'])", {"class": "header-item"}) -assert-css: ("//a[@href='#heading-12']/../following-sibling::ol", {"display": "block"}) +wait-for-attribute: ("li:has(> span > a[href='#heading-12'])", {"class": "header-item expanded"}) +wait-for-attribute: ("li:has(> span > a[href='#heading-21'])", {"class": "header-item"}) +wait-for-css: ("//a[@href='#heading-12']/../following-sibling::ol", {"display": "block"}) +assert-css: ("//a[@href='#heading-21']/../following-sibling::ol", {"display": "none"}) // Click 1.3 click: "a.header-in-summary[href='#heading-13']" // Everything should be collapsed -assert-attribute: ("li:has(> span > a[href='#heading-12'])", {"class": "header-item"}) -assert-attribute: ("li:has(> span > a[href='#heading-21'])", {"class": "header-item"}) -assert-css: ("//a[@href='#heading-12']/../following-sibling::ol", {"display": "none"}) -assert-css: ("//a[@href='#heading-21']/../following-sibling::ol", {"display": "none"}) -assert-attribute: ("li:has(> span > a[href='#heading-12'])", {"class": "header-item"}) -assert-attribute: ("li:has(> span > a[href='#heading-21'])", {"class": "header-item"}) -assert-attribute: ("li:has(> span > a[href='#heading-211'])", {"class": "header-item"}) -assert-attribute: ("li:has(> span > a[href='#heading-2111'])", {"class": "header-item"}) +wait-for-attribute: ("li:has(> span > a[href='#heading-12'])", {"class": "header-item"}) +wait-for-attribute: ("li:has(> span > a[href='#heading-21'])", {"class": "header-item"}) +wait-for-css: ("//a[@href='#heading-12']/../following-sibling::ol", {"display": "none"}) +wait-for-css: ("//a[@href='#heading-21']/../following-sibling::ol", {"display": "none"}) +wait-for-attribute: ("li:has(> span > a[href='#heading-211'])", {"class": "header-item"}) +wait-for-attribute: ("li:has(> span > a[href='#heading-2111'])", {"class": "header-item"}) // Scroll to bottom of page press-key: 'PageDown' @@ -48,11 +49,11 @@ press-key: 'PageDown' press-key: 'PageDown' press-key: 'PageDown' // 2.1.1.1.1 should be visible, and all the chevrons should be open, and expanded should be on each one -assert-attribute: ("li:has(> span > a[href='#heading-12'])", {"class": "header-item"}) -assert-attribute: ("li:has(> span > a[href='#heading-21'])", {"class": "header-item expanded"}) -assert-attribute: ("li:has(> span > a[href='#heading-211'])", {"class": "header-item expanded"}) -assert-attribute: ("li:has(> span > a[href='#heading-2111'])", {"class": "header-item expanded"}) -assert-css: ("//a[@href='#heading-12']/../following-sibling::ol", {"display": "none"}) -assert-css: ("//a[@href='#heading-21']/../following-sibling::ol", {"display": "block"}) -assert-css: ("//a[@href='#heading-211']/../following-sibling::ol", {"display": "block"}) -assert-css: ("//a[@href='#heading-2111']/../following-sibling::ol", {"display": "block"}) +wait-for-attribute: ("li:has(> span > a[href='#heading-12'])", {"class": "header-item"}) +wait-for-attribute: ("li:has(> span > a[href='#heading-21'])", {"class": "header-item expanded"}) +wait-for-attribute: ("li:has(> span > a[href='#heading-211'])", {"class": "header-item expanded"}) +wait-for-attribute: ("li:has(> span > a[href='#heading-2111'])", {"class": "header-item expanded"}) +wait-for-css: ("//a[@href='#heading-12']/../following-sibling::ol", {"display": "none"}) +wait-for-css: ("//a[@href='#heading-21']/../following-sibling::ol", {"display": "block"}) +wait-for-css: ("//a[@href='#heading-211']/../following-sibling::ol", {"display": "block"}) +wait-for-css: ("//a[@href='#heading-2111']/../following-sibling::ol", {"display": "block"}) From dc2fbde51587be5e887e0b59ee07ae5e21af3fc1 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 20 Apr 2026 15:46:20 -0700 Subject: [PATCH 2/2] Harden move-between-pages and sidebar-scroll tests These tests have been randomly failing on CI. I'm not entirely certain why there is a race for these conditions. I'm not sure how browser-ui-test waits when the document reloads on navigation. There's also some javascript triggers that happen after the page loads, and I don't remember if that runs before DOMContentLoaded. --- tests/gui/move-between-pages.goml | 24 ++++++++++++------------ tests/gui/sidebar-scroll.goml | 15 ++++++++------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/tests/gui/move-between-pages.goml b/tests/gui/move-between-pages.goml index 227dcee6..8bcd867c 100644 --- a/tests/gui/move-between-pages.goml +++ b/tests/gui/move-between-pages.goml @@ -3,41 +3,41 @@ go-to: |DOC_PATH| + "all-summary/index.html" // default page is the first chapter -assert-text: ("title", "Prefix 1 - all-summary") +wait-for-text: ("title", "Prefix 1 - all-summary") // Trying to move to the left beyond the prefix pages - nothing changes press-key: 'ArrowLeft' -assert-text: ("title", "Prefix 1 - all-summary") +wait-for-text: ("title", "Prefix 1 - all-summary") // Move left go-to: |DOC_PATH| + "all-summary/intro.html" -assert-text: ("title", "Introduction - all-summary") +wait-for-text: ("title", "Introduction - all-summary") press-key: 'ArrowLeft' -assert-text: ("title", "Prefix 2 - all-summary") +wait-for-text: ("title", "Prefix 2 - all-summary") press-key: 'ArrowLeft' -assert-text: ("title", "Prefix 1 - all-summary") +wait-for-text: ("title", "Prefix 1 - all-summary") // Move right press-key: 'ArrowRight' -assert-text: ("title", "Prefix 2 - all-summary") +wait-for-text: ("title", "Prefix 2 - all-summary") press-key: 'ArrowRight' -assert-text: ("title", "Introduction - all-summary") +wait-for-text: ("title", "Introduction - all-summary") press-key: 'ArrowRight' -assert-text: ("title", "P1 C1 - all-summary") +wait-for-text: ("title", "P1 C1 - all-summary") press-key: 'ArrowRight' -assert-text: ("title", "P2 C1 - all-summary") +wait-for-text: ("title", "P2 C1 - all-summary") press-key: 'ArrowRight' -assert-text: ("title", "Suffix 1 - all-summary") +wait-for-text: ("title", "Suffix 1 - all-summary") press-key: 'ArrowRight' -assert-text: ("title", "Suffix 2 - all-summary") +wait-for-text: ("title", "Suffix 2 - all-summary") // Try to go beyond the last page press-key: 'ArrowRight' -assert-text: ("title", "Suffix 2 - all-summary") +wait-for-text: ("title", "Suffix 2 - all-summary") diff --git a/tests/gui/sidebar-scroll.goml b/tests/gui/sidebar-scroll.goml index fd286e69..b0e40082 100644 --- a/tests/gui/sidebar-scroll.goml +++ b/tests/gui/sidebar-scroll.goml @@ -7,11 +7,11 @@ assert-property: (".sidebar-scrollbox", {"scrollTop": 0}) click: ".chapter a[href='chapter_2.html']" assert-text: ("title", "Chapter 2 - sidebar-scroll") -assert-property: (".sidebar-scrollbox", {"scrollTop": 0}) +wait-for-property: (".sidebar-scrollbox", {"scrollTop": 0}) click: ".chapter a[href='chapter_10.html']" assert-text: ("title", "Chapter 10 - sidebar-scroll") -assert-property: (".sidebar-scrollbox", {"scrollTop": 0}) +wait-for-property: (".sidebar-scrollbox", {"scrollTop": 0}) // Check that heading nav of chapter 10 pushes 11 off the bottom. store-position: (".chapter a[href='chapter_11.html']", {"y": chapter_y}) @@ -21,7 +21,7 @@ assert: |chapter_y| > |windowHeight| // in position since there are only a few lines above. click: ".chapter a[href='chapter_11.html']" assert-text: ("title", "Chapter 11 - sidebar-scroll") -assert-property: (".sidebar-scrollbox", {"scrollTop": 0}) +wait-for-property: (".sidebar-scrollbox", {"scrollTop": 0}) // Scroll down a little, and click on a chapter that can stay in place when // clicked. @@ -30,11 +30,12 @@ store-property: (".sidebar-scrollbox", {"scrollTop": sidebarScrollTop}) assert: |sidebarScrollTop| > 0 click: ".chapter a[href='chapter_35.html']" assert-text: ("title", "Chapter 35 - sidebar-scroll") -assert-property: (".sidebar-scrollbox", {"scrollTop": |sidebarScrollTop|}) +wait-for-property: (".sidebar-scrollbox", {"scrollTop": |sidebarScrollTop|}) // Go to the next chapter, and verify that it scrolls to the middle. press-key: "ArrowRight" assert-text: ("title", "Chapter 36 - sidebar-scroll") +wait-for: ".chapter a.active" // The active link should be roughly in the middle of the screen. store-position: (".chapter a.active", {"y": active_y}) // Approximate check just in case the browser has slight rendering differences. @@ -45,7 +46,7 @@ assert: |active_y| < 450 store-property: (".sidebar-scrollbox", {"scrollTop": sidebarScrollTop}) click: ".chapter a[href='chapter_24.html']" assert-text: ("title", "Chapter 24 - sidebar-scroll") -assert-property: (".sidebar-scrollbox", {"scrollTop": |sidebarScrollTop|}) +wait-for-property: (".sidebar-scrollbox", {"scrollTop": |sidebarScrollTop|}) // Go to the last chapter, and verify it is scrolled to the bottom. go-to: |DOC_PATH| + "sidebar-scroll/chapter_100.html" @@ -57,9 +58,9 @@ assert: |scrollTop| >= |scrollHeight| - |clientHeight| - 1 store-property: (".sidebar-scrollbox", {"scrollTop": sidebarScrollTop}) click: ".chapter a[href='chapter_97.html']" assert-text: ("title", "Chapter 97 - sidebar-scroll") -assert-property: (".sidebar-scrollbox", {"scrollTop": |sidebarScrollTop|}) +wait-for-property: (".sidebar-scrollbox", {"scrollTop": |sidebarScrollTop|}) store-property: (".sidebar-scrollbox", {"scrollTop": sidebarScrollTop}) click: ".chapter a[href='chapter_76.html']" assert-text: ("title", "Chapter 76 - sidebar-scroll") -assert-property: (".sidebar-scrollbox", {"scrollTop": |sidebarScrollTop|}) +wait-for-property: (".sidebar-scrollbox", {"scrollTop": |sidebarScrollTop|})