Skip to content

Commit

Permalink
Fix answerOnNext prompt
Browse files Browse the repository at this point in the history
Thanks to vmi/selenese-runner-java#327

Signed-off-by: Maxim Zhiburt <zhiburt@gmail.com>
  • Loading branch information
zhiburt committed Jul 5, 2021
1 parent 11049c1 commit c59895d
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 65 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ serde = "1.0.126"
regex = "1.5.4"
url = "2.2.2"
async-trait = "0.1"
cfg-if = "1.0.0"

[dev-dependencies]
tokio = { version = "1.6.1", features = ["full"] }
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ You can tweak `fantoccini` backend by providing a feature `fantoccini_backend` a
[`Selenium IDE`] supports the following [commands](https://www.selenium.dev/selenium-ide/docs/en/api/commands).

- [ ] add selection
- [ ] answer on next prompt
- [x] answer on next prompt
- [x] assert
- [x] assert alert
- [x] assert checked
Expand Down
11 changes: 11 additions & 0 deletions js_lib/answerOnNextPrompt.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
function answerOnNextPrompt(answer) {
var canUseLocalStorage = false;
try { canUseLocalStorage = !!window.localStorage; } catch (ex) { /* probe failed */ }
var canUseJSON = false;
try { canUseJSON = !!JSON; } catch (ex) { /* probe failed */ }
if (canUseLocalStorage && canUseJSON) {
window.localStorage.setItem('__webdriverNextPrompt', JSON.stringify(answer));
} else {
window.__webdriverNextPrompt = answer;
}
}
68 changes: 68 additions & 0 deletions js_lib/replaceAlertMethod.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// 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

function replaceAlertMethod(element) {
if (!window.__isReplacedAlertMethod) {
window.__isReplacedAlertMethod = true;
var canUseLocalStorage = false;
try { canUseLocalStorage = !!window.localStorage; } catch (ex) { /* probe failed */ }
var canUseJSON = false;
try { canUseJSON = !!JSON; } catch (ex) { /* probe failed */ }
if (canUseLocalStorage && canUseJSON) {
window.localStorage.setItem('__webdriverAlerts', JSON.stringify([]));
window.alert = function (msg) {
var alerts = JSON.parse(window.localStorage.getItem('__webdriverAlerts'));
alerts.push(msg);
window.localStorage.setItem('__webdriverAlerts', JSON.stringify(alerts));
};
window.localStorage.setItem('__webdriverConfirms', JSON.stringify([]));
if (!('__webdriverNextConfirm' in window.localStorage))
window.localStorage.setItem('__webdriverNextConfirm', JSON.stringify(true));
window.confirm = function (msg) {
var confirms = JSON.parse(window.localStorage.getItem('__webdriverConfirms'));
confirms.push(msg);
window.localStorage.setItem('__webdriverConfirms', JSON.stringify(confirms));
var res = JSON.parse(window.localStorage.getItem('__webdriverNextConfirm'));
window.localStorage.setItem('__webdriverNextConfirm', JSON.stringify(true));
return res;
};
window.localStorage.setItem('__webdriverPrompts', JSON.stringify([]));
if (!('__webdriverNextPrompt' in window.localStorage))
window.localStorage.setItem('__webdriverNextPrompt', JSON.stringify(""));
window.prompt = function (msg) {
var prompts = JSON.parse(window.localStorage.getItem('__webdriverPrompts'));
prompts.push(msg);
window.localStorage.setItem('__webdriverPrompts', JSON.stringify(prompts));
var res = JSON.parse(window.localStorage.getItem('__webdriverNextPrompt'));
window.localStorage.setItem('__webdriverNextPrompt', JSON.stringify(""));
return res;
};
} else {
window.__webdriverAlerts = [];
window.alert = function (msg) { window.__webdriverAlerts.push(msg); };
window.__webdriverConfirms = [];
if (typeof window.__webdriverNextConfirm === 'undefined')
window.__webdriverNextConfirm = true;
window.confirm = function (msg) {
window.__webdriverConfirms.push(msg);
var res = window.__webdriverNextConfirm;
window.__webdriverNextConfirm = true;
return res;
};
window.__webdriverPrompts = [];
if (typeof window.__webdriverNextPrompt === 'undefined')
window.__webdriverNextPrompt = true;
window.prompt = function (msg, def) {
window.__webdriverPrompts.push(msg || def);
var res = window.__webdriverNextPrompt;
window.__webdriverNextPrompt = true;
return res;
};
}
}
var fw;
if (element && (fw = element.ownerDocument.defaultView) && fw != window) {
fw.alert = window.alert;
fw.confirm = window.confirm;
fw.prompt = window.prompt;
}
}
61 changes: 2 additions & 59 deletions src/command/answer_on_next_prompt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use super::Command;
use crate::{error::RunnerErrorKind, webdriver::Webdriver};
use crate::{error::RunnerErrorKind, js_lib, webdriver::Webdriver};

pub struct AnswerOnNextPrompt {
answer: String,
Expand All @@ -18,63 +18,6 @@ impl AnswerOnNextPrompt {
#[async_trait::async_trait]
impl<D: Webdriver> Command<D> for AnswerOnNextPrompt {
async fn run(&self, runner: &mut crate::runner::Runner<D>) -> Result<(), RunnerErrorKind> {
let override_confirm_alert = concat!(
"var canUseLocalStorage = false; ",
"try { canUseLocalStorage = !!window.localStorage; } catch(ex) { /* probe failed */ }",
"var canUseJSON = false; ",
"try { canUseJSON = !!JSON; } catch(ex) { /* probe failed */ } ",
"if (canUseLocalStorage && canUseJSON) { ",
" window.localStorage.setItem('__webdriverAlerts', JSON.stringify([])); ",
" window.alert = function(msg) { ",
" var alerts = JSON.parse(window.localStorage.getItem('__webdriverAlerts')); ",
" alerts.push(msg); ",
" window.localStorage.setItem('__webdriverAlerts', JSON.stringify(alerts)); ",
" }; ",
" window.localStorage.setItem('__webdriverConfirms', JSON.stringify([])); ",
" if (!('__webdriverNextConfirm' in window.localStorage)) { ",
" window.localStorage.setItem('__webdriverNextConfirm', JSON.stringify(true)); ",
" } ",
" window.confirm = function(msg) { ",
" var confirms = JSON.parse(window.localStorage.getItem('__webdriverConfirms')); ",
" confirms.push(msg); ",
" window.localStorage.setItem('__webdriverConfirms', JSON.stringify(confirms)); ",
" var res = JSON.parse(window.localStorage.getItem('__webdriverNextConfirm')); ",
" window.localStorage.setItem('__webdriverNextConfirm', JSON.stringify(true)); ",
" return res; ",
" }; ",
"} else { ",
" if (window.__webdriverAlerts) { return; } ",
" window.__webdriverAlerts = []; ",
" window.alert = function(msg) { window.__webdriverAlerts.push(msg); }; ",
" window.__webdriverConfirms = []; ",
" window.__webdriverNextConfirm = true; ",
" window.confirm = function(msg) { ",
" window.__webdriverConfirms.push(msg); ",
" var res = window.__webdriverNextConfirm; ",
" window.__webdriverNextConfirm = true; ",
" return res; ",
" }; ",
"}",
);

let js = r"
function answerOnNextPrompt(answer) {
var canUseLocalStorage = false;
try { canUseLocalStorage = !!window.localStorage; } catch(ex) { /* probe failed */ }
var canUseJSON = false;
try { canUseJSON = !!JSON; } catch(ex) { /* probe failed */ }
if (canUseLocalStorage && canUseJSON) {
window.localStorage.setItem('__webdriverNextPrompt', JSON.stringify(answer));
} else {
window.__webdriverNextPrompt = answer;
}
}";

let js = format!("{} \n answerOnNextPrompt({:?});", js, self.answer);

runner.exec(&override_confirm_alert).await?;
runner.exec(&js).await?;

Ok(())
js_lib::answer_on_next_prompt(runner, &self.answer).await
}
}
33 changes: 33 additions & 0 deletions src/js_lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use crate::{error::RunnerErrorKind, runner::Runner, webdriver::Webdriver};

macro_rules! include_func {
($file:expr $(,)?) => {{
#[cfg(unix)]
{
include_str!(concat!("../js_lib/", $file))
}
#[cfg(windows)]
{
include_str!(concat!("..\\js_lib\\", $file))
}
}};
}

const REPLACE_ALERT_METHOD: &str = include_func!("replaceAlertMethod.js");
const ANSWER_ON_NEXT_PROMPT: &str = include_func!("answerOnNextPrompt.js");

pub async fn answer_on_next_prompt<D>(
runner: &mut Runner<D>,
answer: &str,
) -> Result<(), RunnerErrorKind>
where
D: Webdriver,
{
let code = format!(
"{}{} replaceAlertMethod(null); answerOnNextPrompt({:?});",
REPLACE_ALERT_METHOD, ANSWER_ON_NEXT_PROMPT, answer
);

runner.exec(&code).await?;
Ok(())
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
mod command;
mod error;
mod js_lib;
mod parser;
mod playground;
#[cfg(test)]
Expand Down
9 changes: 4 additions & 5 deletions tests/all.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,10 @@ test_file!(
"tests/resources/commands/add selection/test.side.json",
command_add_selection
);
// currently fails ...
// test_file!(
// "tests/resources/commands/answer on next prompt/test.side.json",
// command_answer_on_next_prompt
// );
test_file!(
"tests/resources/commands/answer on next prompt/test.side.json",
command_answer_on_next_prompt
);
#[cfg(not(feature = "fantoccini_backend"))]
test_file!(
"tests/resources/commands/assert alert/test.side.json",
Expand Down

0 comments on commit c59895d

Please sign in to comment.