Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFB can not handle two consecutives alerts #3785

Open
wojtekwp opened this issue Sep 12, 2024 · 5 comments
Open

RFB can not handle two consecutives alerts #3785

wojtekwp opened this issue Sep 12, 2024 · 5 comments
Labels
bug Something isn't working priority: medium

Comments

@wojtekwp
Copy link

Describe the bug
RFB not able to handle two consecutives alerts. It fails with below message:

TimeoutError: page.waitForEvent: Timeout 5000ms exceeded while waiting for event “dialog”
=========================== logs ===========================
waiting for event “dialog”
Tip: Use “Set Browser Timeout” for increasing the timeout.

To Reproduce
I prep 2 simple files to easily reproduce an issue. Create new folder and copy 2 files content ex. to c:/alert_demo, then run start CMDs

cd c:/alert_demo
robot -d example/1 -t Alert-Debug example.robot
  • 1 file (index.html) - example page with 2 consecutive alerts (one alert after another)
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Multiple alerts issue - example</title>
</head>
<body>
    <button onclick="showAlerts()">Click to show alerts</button>

    <script>
        function showAlerts() {
            confirm("First alert accepted?");
            alert("Second alert!");
        }
    </script>
</body>
</html>
  • 2 file (example.robot) - steps followed to reproduce an issue.
    Please notice on line 8 it needs to be correct index.html path to open sample page with 2 alerts :
*** Settings ***
Library    Browser

*** Test Cases ***
Alert-Debug
    Browser Setup
    #provide correct index.html path below
    Go To    C:/alert_demo/index.html
    Click    //button
    Validate Alert Response    First alert accepted?
    Validate Alert Response    Second alert!

*** Keywords ***
Browser Setup
    Set Browser Timeout    30
    New Browser     browser=chromium     headless=false    args=["--start-maximized"]
    New Context    viewport=${None}
    New Page        url=about:blank

Validate Alert Response
    [Arguments]     ${messageValue}
    ${message} =    Wait For Alert    action=accept    text=${messageValue}    timeout=5

Expected behavior
Two alerts should be handled correctly

Desktop :
chromium
Win 11 E
Python 3.11.9
NodeJS v20.15.1
Browser library 18.6.3
Robot Framework version: 7.0.1
Playwright 1.45.0

Additional context
More details: https://forum.robotframework.org/t/can-not-handle-two-consecutives-alerts/3347

@aaltat aaltat added bug Something isn't working priority: medium labels Sep 13, 2024
@aaltat
Copy link
Member

aaltat commented Sep 13, 2024

@allcontributors please add @wojtekwp for bugs.

Copy link
Contributor

@aaltat

I've put up a pull request to add @wojtekwp! 🎉

@aaltat
Copy link
Member

aaltat commented Sep 28, 2024

Playwright does not allow to register two dialog handlers and therefore it crashes. I think that is by design. But I can also see a problem, because if you do only this:

    ${promise} =    Promise To    Wait For Alert    action=accept    timeout=5
    Click    id=alert
    ${text} =    Wait For      ${promise}
    Log    ${text}

You get only text from first alter and not from the second on. The second on is automatically dismissed by Playwright.

The problem can be solved by changing the code to of the page to call multiple times waitForEvent, but problem is that current keyword does not allow one to define different actions or expect different text for the alert. Like your example, you are excepting alerts to have different texts.

To solve problem correctly, we would need new keyword which would allow handling one or more alerts. Also that keyword should allow handling each alert differently, meaning have different values for action, prompt_inputand text (I think same timeout can be used for all alerts.) But what would be good name and syntax for this new keyword?

One option could be to kwargs and suffix each alert handling with number.
Example this would handle two different alerts:

    ${promise}    Promise To    Wait For Alerts    action1=accecpt    text1=Text One Here    action2=dismiss    text2=Two is here
    Click    id=alert
    ${text} =            Wait For      ${promise}    # ${text} would be list of two string

But there could better ways to define handling of multiple alerts and I am open to ideas? Would you idea for keyword syntax?

@wojtekwp
Copy link
Author

I tried to add below snippet to Browser\keywords\interaction.py and prep next rfb example code with declared list variable & promise but it not always works as expected - don't know why but sometimes still failing to catch and retrieve response from dialog within expected 5s timeout.

If this "Wait For Alerts" keyword fails please try several times - it's not stable - works as expected usually 4/10 tries, sometimes more.

  • add below to interaction.py
@keyword(tags=("Wait", "PageContent"))
def wait_for_alerts(
    self,
    actions: List[DialogAction],
    prompt_inputs: List[str] = None,
    texts: List[Optional[str]] = None,
    timeout: Optional[timedelta] = None,
):
    if prompt_inputs is None:
        prompt_inputs = [""] * len(actions)
    if texts is None:
        texts = [None] * len(actions)

    responses = []
    for i, action in enumerate(actions):
        with self.playwright.grpc_channel() as stub:
            response = stub.WaitForAlert(
                Request().AlertAction(
                    alertAction=action.name,
                    promptInput=prompt_inputs[i],
                    timeout=self.get_timeout(timeout),
                )
            )
        logger.debug(response.log)
        if texts[i] is not None:
            assert (
                texts[i] == response.body
            ), f'Alert text was: "{response.body}" but it should have been: "{texts[i]}"'
        else:
            logger.debug("Not verifying alert text.")
        responses.append(response.body)
    return responses
  • example.py
*** Settings ***
Library    Browser

*** Variables ***
@{ACTIONS}    accept    dismiss
@{TEXTS}      First alert accepted?    Second alert!
#@{TEXTS}      First alert acceptedd?    Second alerttt!

*** Test Cases ***
Alert-Debug
    Browser Setup
    #provide correct index.html path below
    Go To    C:/alert_demo/index.html
    Click    //button
    Validate Alert Response    First alert accepted?
    Validate Alert Response    Second alert!

Alert-Debug2
    Browser Setup
    #provide correct index.html path below
    Go To    C:/alert_demo/index.html
    ${promise} =    Promise To    Wait For Alerts    actions=${ACTIONS}    texts=${TEXTS}    timeout=5	
    Click    //button
    ${texts} =    Wait For    ${promise}
    Log    ${texts}
	
*** Keywords ***
Browser Setup
    Set Browser Timeout    30
    New Browser     browser=chromium     headless=false    args=["--start-maximized"]
    New Context    viewport=${None}
    New Page        url=about:blank

Validate Alert Response
    [Arguments]     ${messageValue}
    ${message} =    Wait For Alert    action=accept    text=${messageValue}    timeout=5
  • execute from cmd with

cd c:/alert_demo
robot -d example/2 -t Alert-Debug2 example.robot

@aaltat
Copy link
Member

aaltat commented Sep 30, 2024

There is also changes needed in the node side. In any case, your way to declare keyword syntax is valid one, because then automatic argument conversion should work. The downside might be that if there are many alerts, seeing what arguments belongs to which alert may come hard. But I think that is pretty rare case, because handling many alerts is not that common. I think if better ideas don’t arrive, I will go with this approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working priority: medium
Projects
None yet
Development

No branches or pull requests

2 participants