Closed wojtekwp closed 1 month ago
@allcontributors please add @wojtekwp for bugs.
@aaltat
I've put up a pull request to add @wojtekwp! :tada:
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_input
and 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?
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
*** Settings ***
Library Browser
Variables @{ACTIONS} accept dismiss @{TEXTS} First alert accepted? Second alert!
Test Cases Alert-Debug Browser Setup
Go To C:/alert_demo/index.html
Click //button
Validate Alert Response First alert accepted?
Validate Alert Response Second alert!
Alert-Debug2 Browser Setup
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
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.
Describe the bug RFB not able to handle two consecutives alerts. It fails with below message:
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
Test Cases Alert-Debug Browser Setup
provide correct index.html path below
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