Skip to content

Commit c59895d

Browse files
committed
Fix answerOnNext prompt
Thanks to vmi/selenese-runner-java#327 Signed-off-by: Maxim Zhiburt <[email protected]>
1 parent 11049c1 commit c59895d

File tree

8 files changed

+121
-65
lines changed

8 files changed

+121
-65
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ serde = "1.0.126"
2626
regex = "1.5.4"
2727
url = "2.2.2"
2828
async-trait = "0.1"
29+
cfg-if = "1.0.0"
2930

3031
[dev-dependencies]
3132
tokio = { version = "1.6.1", features = ["full"] }

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ You can tweak `fantoccini` backend by providing a feature `fantoccini_backend` a
5858
[`Selenium IDE`] supports the following [commands](https://www.selenium.dev/selenium-ide/docs/en/api/commands).
5959

6060
- [ ] add selection
61-
- [ ] answer on next prompt
61+
- [x] answer on next prompt
6262
- [x] assert
6363
- [x] assert alert
6464
- [x] assert checked

js_lib/answerOnNextPrompt.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
function answerOnNextPrompt(answer) {
2+
var canUseLocalStorage = false;
3+
try { canUseLocalStorage = !!window.localStorage; } catch (ex) { /* probe failed */ }
4+
var canUseJSON = false;
5+
try { canUseJSON = !!JSON; } catch (ex) { /* probe failed */ }
6+
if (canUseLocalStorage && canUseJSON) {
7+
window.localStorage.setItem('__webdriverNextPrompt', JSON.stringify(answer));
8+
} else {
9+
window.__webdriverNextPrompt = answer;
10+
}
11+
}

js_lib/replaceAlertMethod.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// The credit for the function https://github.com/vmi/selenese-runner-java/blob/ca8511e6baa20939148edff2a139b4de2e1c11e7/src/main/resources/jp/vmi/selenium/selenese/javascript/JSLibrary.js#L28
2+
3+
function replaceAlertMethod(element) {
4+
if (!window.__isReplacedAlertMethod) {
5+
window.__isReplacedAlertMethod = true;
6+
var canUseLocalStorage = false;
7+
try { canUseLocalStorage = !!window.localStorage; } catch (ex) { /* probe failed */ }
8+
var canUseJSON = false;
9+
try { canUseJSON = !!JSON; } catch (ex) { /* probe failed */ }
10+
if (canUseLocalStorage && canUseJSON) {
11+
window.localStorage.setItem('__webdriverAlerts', JSON.stringify([]));
12+
window.alert = function (msg) {
13+
var alerts = JSON.parse(window.localStorage.getItem('__webdriverAlerts'));
14+
alerts.push(msg);
15+
window.localStorage.setItem('__webdriverAlerts', JSON.stringify(alerts));
16+
};
17+
window.localStorage.setItem('__webdriverConfirms', JSON.stringify([]));
18+
if (!('__webdriverNextConfirm' in window.localStorage))
19+
window.localStorage.setItem('__webdriverNextConfirm', JSON.stringify(true));
20+
window.confirm = function (msg) {
21+
var confirms = JSON.parse(window.localStorage.getItem('__webdriverConfirms'));
22+
confirms.push(msg);
23+
window.localStorage.setItem('__webdriverConfirms', JSON.stringify(confirms));
24+
var res = JSON.parse(window.localStorage.getItem('__webdriverNextConfirm'));
25+
window.localStorage.setItem('__webdriverNextConfirm', JSON.stringify(true));
26+
return res;
27+
};
28+
window.localStorage.setItem('__webdriverPrompts', JSON.stringify([]));
29+
if (!('__webdriverNextPrompt' in window.localStorage))
30+
window.localStorage.setItem('__webdriverNextPrompt', JSON.stringify(""));
31+
window.prompt = function (msg) {
32+
var prompts = JSON.parse(window.localStorage.getItem('__webdriverPrompts'));
33+
prompts.push(msg);
34+
window.localStorage.setItem('__webdriverPrompts', JSON.stringify(prompts));
35+
var res = JSON.parse(window.localStorage.getItem('__webdriverNextPrompt'));
36+
window.localStorage.setItem('__webdriverNextPrompt', JSON.stringify(""));
37+
return res;
38+
};
39+
} else {
40+
window.__webdriverAlerts = [];
41+
window.alert = function (msg) { window.__webdriverAlerts.push(msg); };
42+
window.__webdriverConfirms = [];
43+
if (typeof window.__webdriverNextConfirm === 'undefined')
44+
window.__webdriverNextConfirm = true;
45+
window.confirm = function (msg) {
46+
window.__webdriverConfirms.push(msg);
47+
var res = window.__webdriverNextConfirm;
48+
window.__webdriverNextConfirm = true;
49+
return res;
50+
};
51+
window.__webdriverPrompts = [];
52+
if (typeof window.__webdriverNextPrompt === 'undefined')
53+
window.__webdriverNextPrompt = true;
54+
window.prompt = function (msg, def) {
55+
window.__webdriverPrompts.push(msg || def);
56+
var res = window.__webdriverNextPrompt;
57+
window.__webdriverNextPrompt = true;
58+
return res;
59+
};
60+
}
61+
}
62+
var fw;
63+
if (element && (fw = element.ownerDocument.defaultView) && fw != window) {
64+
fw.alert = window.alert;
65+
fw.confirm = window.confirm;
66+
fw.prompt = window.prompt;
67+
}
68+
}

src/command/answer_on_next_prompt.rs

Lines changed: 2 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
44

55
use super::Command;
6-
use crate::{error::RunnerErrorKind, webdriver::Webdriver};
6+
use crate::{error::RunnerErrorKind, js_lib, webdriver::Webdriver};
77

88
pub struct AnswerOnNextPrompt {
99
answer: String,
@@ -18,63 +18,6 @@ impl AnswerOnNextPrompt {
1818
#[async_trait::async_trait]
1919
impl<D: Webdriver> Command<D> for AnswerOnNextPrompt {
2020
async fn run(&self, runner: &mut crate::runner::Runner<D>) -> Result<(), RunnerErrorKind> {
21-
let override_confirm_alert = concat!(
22-
"var canUseLocalStorage = false; ",
23-
"try { canUseLocalStorage = !!window.localStorage; } catch(ex) { /* probe failed */ }",
24-
"var canUseJSON = false; ",
25-
"try { canUseJSON = !!JSON; } catch(ex) { /* probe failed */ } ",
26-
"if (canUseLocalStorage && canUseJSON) { ",
27-
" window.localStorage.setItem('__webdriverAlerts', JSON.stringify([])); ",
28-
" window.alert = function(msg) { ",
29-
" var alerts = JSON.parse(window.localStorage.getItem('__webdriverAlerts')); ",
30-
" alerts.push(msg); ",
31-
" window.localStorage.setItem('__webdriverAlerts', JSON.stringify(alerts)); ",
32-
" }; ",
33-
" window.localStorage.setItem('__webdriverConfirms', JSON.stringify([])); ",
34-
" if (!('__webdriverNextConfirm' in window.localStorage)) { ",
35-
" window.localStorage.setItem('__webdriverNextConfirm', JSON.stringify(true)); ",
36-
" } ",
37-
" window.confirm = function(msg) { ",
38-
" var confirms = JSON.parse(window.localStorage.getItem('__webdriverConfirms')); ",
39-
" confirms.push(msg); ",
40-
" window.localStorage.setItem('__webdriverConfirms', JSON.stringify(confirms)); ",
41-
" var res = JSON.parse(window.localStorage.getItem('__webdriverNextConfirm')); ",
42-
" window.localStorage.setItem('__webdriverNextConfirm', JSON.stringify(true)); ",
43-
" return res; ",
44-
" }; ",
45-
"} else { ",
46-
" if (window.__webdriverAlerts) { return; } ",
47-
" window.__webdriverAlerts = []; ",
48-
" window.alert = function(msg) { window.__webdriverAlerts.push(msg); }; ",
49-
" window.__webdriverConfirms = []; ",
50-
" window.__webdriverNextConfirm = true; ",
51-
" window.confirm = function(msg) { ",
52-
" window.__webdriverConfirms.push(msg); ",
53-
" var res = window.__webdriverNextConfirm; ",
54-
" window.__webdriverNextConfirm = true; ",
55-
" return res; ",
56-
" }; ",
57-
"}",
58-
);
59-
60-
let js = r"
61-
function answerOnNextPrompt(answer) {
62-
var canUseLocalStorage = false;
63-
try { canUseLocalStorage = !!window.localStorage; } catch(ex) { /* probe failed */ }
64-
var canUseJSON = false;
65-
try { canUseJSON = !!JSON; } catch(ex) { /* probe failed */ }
66-
if (canUseLocalStorage && canUseJSON) {
67-
window.localStorage.setItem('__webdriverNextPrompt', JSON.stringify(answer));
68-
} else {
69-
window.__webdriverNextPrompt = answer;
70-
}
71-
}";
72-
73-
let js = format!("{} \n answerOnNextPrompt({:?});", js, self.answer);
74-
75-
runner.exec(&override_confirm_alert).await?;
76-
runner.exec(&js).await?;
77-
78-
Ok(())
21+
js_lib::answer_on_next_prompt(runner, &self.answer).await
7922
}
8023
}

src/js_lib.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
use crate::{error::RunnerErrorKind, runner::Runner, webdriver::Webdriver};
2+
3+
macro_rules! include_func {
4+
($file:expr $(,)?) => {{
5+
#[cfg(unix)]
6+
{
7+
include_str!(concat!("../js_lib/", $file))
8+
}
9+
#[cfg(windows)]
10+
{
11+
include_str!(concat!("..\\js_lib\\", $file))
12+
}
13+
}};
14+
}
15+
16+
const REPLACE_ALERT_METHOD: &str = include_func!("replaceAlertMethod.js");
17+
const ANSWER_ON_NEXT_PROMPT: &str = include_func!("answerOnNextPrompt.js");
18+
19+
pub async fn answer_on_next_prompt<D>(
20+
runner: &mut Runner<D>,
21+
answer: &str,
22+
) -> Result<(), RunnerErrorKind>
23+
where
24+
D: Webdriver,
25+
{
26+
let code = format!(
27+
"{}{} replaceAlertMethod(null); answerOnNextPrompt({:?});",
28+
REPLACE_ALERT_METHOD, ANSWER_ON_NEXT_PROMPT, answer
29+
);
30+
31+
runner.exec(&code).await?;
32+
Ok(())
33+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
3535
mod command;
3636
mod error;
37+
mod js_lib;
3738
mod parser;
3839
mod playground;
3940
#[cfg(test)]

tests/all.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,10 @@ test_file!(
8282
"tests/resources/commands/add selection/test.side.json",
8383
command_add_selection
8484
);
85-
// currently fails ...
86-
// test_file!(
87-
// "tests/resources/commands/answer on next prompt/test.side.json",
88-
// command_answer_on_next_prompt
89-
// );
85+
test_file!(
86+
"tests/resources/commands/answer on next prompt/test.side.json",
87+
command_answer_on_next_prompt
88+
);
9089
#[cfg(not(feature = "fantoccini_backend"))]
9190
test_file!(
9291
"tests/resources/commands/assert alert/test.side.json",

0 commit comments

Comments
 (0)