1

Currently there is no out of box solution in the Robot Framework libraries on how to wait until the element is visible on the page in shadow DOM. I came up with one approach. Perhaps it will be useful for others.

I created a keyword:

Verify ShadowDom Element Visible
    [Arguments]    ${Element}
    register keyword to run on failure    Capture Page Screenshot
    ${previous_kw}=    register keyword to run on failure    Nothing
    FOR    ${index}    IN RANGE    1    30
        sleep    1s
        ${status2}=    Run Keyword and return Status    execute javascript    return ${Element}.checkVisibility();
        IF    '${status2}'=='False'    CONTINUE
        ...    ELSE    BREAK
    END
    register keyword to run on failure    ${previous_kw}
    IF    '${status2}'=='False'    Capture Page Screenshot
    IF    '${status2}'=='False'    Fail    Element not visible after 30 sec.


Verify ShadowDom Element Visible      document.querySelector("xxxx-block-wizard-footer").shadowRoot.querySelector(".xxxx-block-wizard-footer__cta-primary").shadowRoot.querySelector("button")

In this case, we are expecting some button in shadow DOM to appear on the page within 30 seconds. If button did not appear, a screenshot would be captured and a fail message will be sent to log.

Note: If the button is visible, no screenshot is taken on all the failed attempts to verify. Good luck.

1 Answer 1

0

First of all, thanks for pointing me in the right direction! :) Your keyword contains a bug and a few unnecessary stuff though:

${status2}=    Run Keyword and return Status    execute javascript    return ${Element}.checkVisibility();

this actually returns False only if the javascript returns with an exception (even if the element is not visible)

Here I created a keyword based on your idea, that I think can be used more generally and without the said issues:

Wait Until ShadowDom Element is Visible 
    [Arguments]    ${locator}    ${check_period}=1s    ${max_tries}=30 
    ${try}    Set Variable    ${1} 
    ${max_tries}    Convert To Integer    ${max_tries} 
    #locators are in 'dom:<selector>' format, we need to get rid of the 'dom:' substring
    ${locator}    Replace String    ${locator}    dom:    ${EMPTY} 
    WHILE    ${try} <= ${max_tries}  
        ${element_visible}    Run Keyword And Continue On Failure    Execute Javascript    return ${locator}.checkVisibility();
        # if there is a JavascriptException (ie. the DOM is not fully loaded yet) this returns None
        IF    ${element_visible}    BREAK 
        ${try}    Set Variable    ${try + 1} 
        Sleep    ${check_period} 
    END    
    IF    ${element_visible} 
        Log    Element found at ${locator} 
    ELSE 
        Fail    Element Not Visible at ${locator} 
    END

Not the answer you're looking for? Browse other questions tagged or ask your own question.