NYULibraries / primo-explore-views

A consolidated monorepo of NYU Consortium views
MIT License
2 stars 1 forks source link

libraryh3lp e2e test flake caused by sporadic absence of .libraryh3lp element being tested #384

Closed da70 closed 2 years ago

da70 commented 2 years ago
image

See also CircleCI workflows for July 20-21, 2022 for errors and the commits associated with them. Note alternating success and failure for exact same code under test.

Current theory working theory: either libraryh3lp backend outages or application + network race conditions are causing the .libraryh3lp element to be absent from the DOM. This causes this test to fail in Cypress 10 (which we just upgraded to):

    it('does not have a visible libraryh3lp element', () => {
      cy.get('.libraryh3lp')
        .should('not.be.visible')
    })

This test expects an element with class "libraryh3lp" to always be present but initially hidden. There was a bug in versions of Cypress earlier than 6 to cause cy.get(<ELEMENT>).should('not.be.visible') to false pass if did not exist. Thus regardless of whether the div.libraryh3lp element was present and hidden or not present at all, our test would return true. As of Cypress 6, this test will now fail due to .libraryh3lp being completely absent, not just present and not visible.

These contradictory error messages in the CircleCI output illustrate the point:

AssertionError: Timed out retrying after 12000ms: Expected to find element: `.libraryh3lp`, but never found it.
    at Context.eval (http://web-test:8004/__cypress/tests?p=cypress/e2e/NYU/primo-explore-libraryh3lp-widget.cy.js:108:30)

...and...

AssertionError: Timed out retrying after 12000ms: Expected <div.libraryh3lp> not to exist in the DOM, but it was continuously found.
    at Context.eval (http://web-test:8004/__cypress/tests?p=cypress/e2e/NYU/primo-explore-libraryh3lp-widget.cy.js:108:30)

(Note that the above messages usually were associated with different test code. For a brief period, should(not.be.visible) was replaced with should(not.exist).

We need to eliminate this test flake.


This is very likely a manifestation of the failure mode causing the test failure:

libraryh3lp-error

It tends to clear itself. Haven't managed to get the HTML for it yet. EDIT: Got it:

<prm-silent-login-after parent-ctrl="$ctrl">
  <button class="button chat-tab ss-chat js-toggle-chat" ng-class="$ctrl.klasses" ng-init="showChatWidget = false" ng-click="showChatWidget = !showChatWidget">
    <prm-icon style="z-index:1" icon-type="svg" svg-icon-set="communication" icon-definition="ic_chat_24px">
      <!---->
      <md-icon ng-if="::($ctrl.iconDefinition &amp;&amp; !$ctrl.isCustom &amp;&amp; !$ctrl.isEmailMode())" md-svg-icon="communication:ic_chat_24px" role="presentation" class="md-primoExplore-theme">
        <svg width="100%" height="100%" viewBox="0 0 24 24" id="ic_chat_24px_cache0" y="192" xmlns="http://www.w3.org/2000/svg" fit="" preserveAspectRatio="xMidYMid meet" focusable="false">
          <path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM6 9h12v2H6V9zm8 5H6v-2h8v2zm4-6H6V6h12v2z"></path>
        </svg>
      </md-icon>
      <!---->
      <!---->
      <prm-icon-after parent-ctrl="$ctrl"></prm-icon-after>
    </prm-icon> Chat with us
  </button>
  <div class="chat-frame-wrap" ng-class="$ctrl.klasses" ng-show="showChatWidget" aria-hidden="false" style="">
    <button class="chat-close ss-icon js-toggle-chat" title="Close chat window" ng-click="showChatWidget = !showChatWidget" aria-label="Close chat window">×</button>
    <!---->
    <!---->Chat is offline.
    <!---->
  </div>
</prm-silent-login-after>

Here's what the widget normally looks like (prettified):

image

Here's the HTML for it:

<prm-silent-login-after parent-ctrl="$ctrl">
  <button class="button chat-tab ss-chat js-toggle-chat" ng-class="$ctrl.klasses" ng-init="showChatWidget = false" ng-click="showChatWidget = !showChatWidget">
    <prm-icon style="z-index:1" icon-type="svg" svg-icon-set="communication" icon-definition="ic_chat_24px">
      <!---->
      <md-icon ng-if="::($ctrl.iconDefinition &amp;&amp; !$ctrl.isCustom &amp;&amp; !$ctrl.isEmailMode())" md-svg-icon="communication:ic_chat_24px" role="presentation" class="md-primoExplore-theme">
        <svg width="100%" height="100%" viewBox="0 0 24 24" id="ic_chat_24px_cache11" y="192" xmlns="http://www.w3.org/2000/svg" fit="" preserveAspectRatio="xMidYMid meet" focusable="false">
          <path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM6 9h12v2H6V9zm8 5H6v-2h8v2zm4-6H6V6h12v2z"></path>
        </svg>
      </md-icon>
      <!---->
      <!---->
      <prm-icon-after parent-ctrl="$ctrl"></prm-icon-after>
    </prm-icon> Chat with us
  </button>
  <div class="chat-frame-wrap" ng-class="$ctrl.klasses" ng-show="showChatWidget" aria-hidden="false" style="">
    <button class="chat-close ss-icon js-toggle-chat" title="Close chat window" ng-click="showChatWidget = !showChatWidget" aria-label="Close chat window">×</button>
    <!---->
    <!---->
    <div class="libraryh3lp" style="" data-lh3-jid="nyu-aal-chat@chat.libraryh3lp.com">
      <iframe title="Ask a Librarian chat" src="https://libraryh3lp.com/chat/nyu-aal-chat@chat.libraryh3lp.com?skin=23106" frameborder="1" style="width: 186px; height: 250px; border: 2px solid rgb(192, 192, 192);"></iframe>
    </div>
    <!---->
  </div>
</prm-silent-login-after>

Here's what the widget looks like when it's closed -- and note that it looks like this even when chat is offline (which the user discovers after clicking the button):

image

Here's the HTML for the closed widget (prettified):

<prm-silent-login-after parent-ctrl="$ctrl">
   <button class="button chat-tab ss-chat js-toggle-chat" ng-class="$ctrl.klasses" ng-init="showChatWidget = false" ng-click="showChatWidget = !showChatWidget">
      <prm-icon style="z-index:1" icon-type="svg" svg-icon-set="communication" icon-definition="ic_chat_24px">
         <!---->
         <md-icon ng-if="::($ctrl.iconDefinition &amp;&amp; !$ctrl.isCustom &amp;&amp; !$ctrl.isEmailMode())" md-svg-icon="communication:ic_chat_24px" role="presentation" class="md-primoExplore-theme">
            <svg width="100%" height="100%" viewBox="0 0 24 24" id="ic_chat_24px_cache11" y="192" xmlns="http://www.w3.org/2000/svg" fit="" preserveAspectRatio="xMidYMid meet" focusable="false">
               <path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM6 9h12v2H6V9zm8 5H6v-2h8v2zm4-6H6V6h12v2z"></path>
            </svg>
         </md-icon>
         <!----><!---->
         <prm-icon-after parent-ctrl="$ctrl"></prm-icon-after>
      </prm-icon>
      Chat with us
   </button>
   <div class="chat-frame-wrap ng-hide" ng-class="$ctrl.klasses" ng-show="showChatWidget" aria-hidden="true" style="">
      <button class="chat-close ss-icon js-toggle-chat" title="Close chat window" ng-click="showChatWidget = !showChatWidget" aria-label="Close chat window">×</button>
      <!---->
      <!---->
      <div class="libraryh3lp" style="" data-lh3-jid="nyu-aal-chat@chat.libraryh3lp.com"><iframe title="Ask a Librarian chat" src="https://libraryh3lp.com/chat/nyu-aal-chat@chat.libraryh3lp.com?skin=23106" frameborder="1" style="width: 186px; height: 250px; border: 2px solid rgb(192, 192, 192);"></iframe></div>
      <!---->
   </div>
</prm-silent-login-after>

References


Branch: https://github.com/NYULibraries/primo-explore-views/tree/384_libraryh3lp-e2e-test-flake

da70 commented 2 years ago

'does not have a visible close button' test is broken

One of the tests is broken: https://github.com/NYULibraries/primo-explore-views/blob/3ad500f39ed262f865a8402e875c66ea6b33b1ff/primo-explore-e2e-cypress/cypress/integration/NYU/primo-explore-libraryh3lp-widget.spec.js#L17-L20

button.close-chat should be button.chat-close:

image

A later test does use the correct selector. This is not related to the test flakiness being addressed in this ticket. It is a broken test that always returns a false pass. I'll fix it along with the flaky test (which is also a test of initial load state).

EDIT: Note that the above was from master branch. In development it was recently changed to this:

    it('does not have a visible close button', () => {
      cy.get('button.close-chat')
        .should('not.exist')
    })

...as part of the upgrade of Cypress to 10. It passes because button.chose-chat will never exist regardless of the state of the widget. I'll change it back to not.be.visible -- but note that there is a chance this will fail, because even though the close button is not visible to the human on initial load, the display property is computed value "block":

image

There are many other ways to make an element not visible other than using the display property though, and Cypress probably will know all the methods and check them.

da70 commented 2 years ago

Preliminary research done:

The near-term goal is to get all green for development CircleCI tests so that Vlad can merge into master.

I believe the intent of the flaky test is to establish that widget initially loads in a closed state, with no chat