com.github.markusbernhardt.seleniumlibrary.keywords.JavaScript Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of robotframework-seleniumlibrary Show documentation
Show all versions of robotframework-seleniumlibrary Show documentation
Java port of the Python based SeleniumLibrary for Robot Framework
package com.github.markusbernhardt.seleniumlibrary.keywords;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.Arrays;
import org.openqa.selenium.Alert;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriverException;
import org.robotframework.javalib.annotation.ArgumentNames;
import org.robotframework.javalib.annotation.Autowired;
import org.robotframework.javalib.annotation.RobotKeyword;
import org.robotframework.javalib.annotation.RobotKeywordOverload;
import org.robotframework.javalib.annotation.RobotKeywords;
import com.github.markusbernhardt.seleniumlibrary.RunOnFailureKeywordsAdapter;
import com.github.markusbernhardt.seleniumlibrary.SeleniumLibraryNonFatalException;
import com.github.markusbernhardt.seleniumlibrary.utils.Python;
@RobotKeywords
public class JavaScript extends RunOnFailureKeywordsAdapter {
protected boolean acceptOnNextConfirmationDefault = true;
protected boolean acceptOnNextConfirmation = true;
/**
* Instantiated BrowserManagement keyword bean
*/
@Autowired
protected BrowserManagement browserManagement;
/**
* Instantiated Logging keyword bean
*/
@Autowired
protected Logging logging;
// ##############################
// Keywords
// ##############################
@RobotKeywordOverload
public void alertShouldBePresent() {
alertShouldBePresent("");
}
/**
* Verify an alert is present and dismiss it.
*
* If text is a non-empty string, then it is also verified that the
* message of the alert equals to text.
*
* Will fail if no alert is present. Note that following keywords will fail
* unless the alert is confirmed by this keyword or another like `Confirm
* Action`.
*
* @param text
* Default=NONE. The alert message to verify.
*/
@RobotKeyword
@ArgumentNames({ "text=NONE" })
public void alertShouldBePresent(String text) {
String alertText = confirmAction();
if (text != null && !alertText.equals(text)) {
throw new SeleniumLibraryNonFatalException(String.format("Alert text should have been '%s' but was '%s'",
text, alertText));
}
}
/**
* Cancel will be selected the next time a confirmation dialog appears.
*
* Note that every time a confirmation comes up, it must be confirmed by the
* keywords 'Alert Should Be Present' or `Confirm Action`. Otherwise all
* following operations will fail.
*/
@RobotKeyword
public void chooseCancelOnNextConfirmation() {
acceptOnNextConfirmation = false;
}
/**
* Ok will be selected the next time a confirmation dialog appears.
*
* Note that every time a confirmation comes up, it must be confirmed by the
* keywords 'Alert Should Be Present' or `Confirm Action`. Otherwise all
* following operations will fail.
*/
@RobotKeyword
public void chooseOkOnNextConfirmation() {
acceptOnNextConfirmation = true;
}
/**
* Cancel will as default be selected from now on every time a confirmation
* dialog appears.
*
* Note that every time a confirmation comes up, it must be confirmed by the
* keywords 'Alert Should Be Present' or `Confirm Action`. Otherwise all
* following operations will fail.
*/
@RobotKeyword
public void chooseCancelOnConfirmation() {
acceptOnNextConfirmationDefault = false;
acceptOnNextConfirmation = false;
}
/**
* Ok will as default be selected from now on every time a confirmation
* dialog appears.
*
* Note that every time a confirmation comes up, it must be confirmed by the
* keywords 'Alert Should Be Present' or `Confirm Action`. Otherwise all
* following operations will fail.
*/
@RobotKeyword
public void chooseOkOnConfirmation() {
acceptOnNextConfirmationDefault = true;
acceptOnNextConfirmation = true;
}
/**
* Dismisses currently shown confirmation dialog and returns its message.
*
* By default, this keyword chooses 'OK' option from the dialog. If 'Cancel'
* needs to be chosen, keyword `Choose Cancel On Next Confirmation` must be
* called before the action that causes the confirmation dialog to be shown.
*
* Example:
*
*
* Click Button
* Send
*
* # Shows a confirmation dialog
*
*
* ${message}=
* Confirm Action
*
* # Chooses Ok
*
*
* Should Be Equal
* ${message}
* Are your sure?
* # Check dialog message
*
*
* Choose Cancel On Next Confirmation
*
*
* # Choose cancel on next `Confirm Action`
*
*
* Click Button
* Send
*
* # Shows a confirmation dialog
*
*
* Confirm Action
*
*
* # Chooses Cancel
*
*
*
* @return The dialog message.
*/
@RobotKeyword
public String confirmAction() {
try {
Alert alert = browserManagement.getCurrentWebDriver().switchTo().alert();
String text = alert.getText().replace("\n", "");
if (acceptOnNextConfirmation) {
alert.accept();
} else {
alert.dismiss();
}
acceptOnNextConfirmation = acceptOnNextConfirmationDefault;
return text;
} catch (WebDriverException wde) {
throw new SeleniumLibraryNonFatalException("There were no alerts");
}
}
/**
* Execute the given JavaScript code.
*
* The given code may contain multiple lines of code, but must contain a
* return statement (with the value to be returned) at the end.
*
* The given code may be divided into multiple cells in the test data. In
* that case, the parts are concatenated together without adding spaces. If
* the given code is an absolute path to an existing file, the JavaScript to
* execute will be read from that file. Forward slashes work as a path
* separator on all operating systems.
*
* Note that by default the code will be executed in the context of the
* Selenium object itself, so this will refer to the Selenium object.
* Use window to refer to the window of your application, e.g.
* window.document.getElementById('foo').
*
* Example:
*
*
* Execute JavaScript
* return window.my_js_function('arg1', 'arg2');
* # Directly execute the JavaScript
*
*
* Execute JavaScript
* ${CURDIR}/js_to_execute.js
* # Load the JavaScript to execute from file
*
*
*
* @param code
* The JavaScript code or a file name.
* @return The return value of the executed code.
*/
@RobotKeyword
@ArgumentNames({ "*code" })
public Object executeJavascript(String... code) {
String js = getJavascriptToExecute(Python.join("", Arrays.asList(code)));
String.format("Executing JavaScript:\n%s", js);
return ((JavascriptExecutor) browserManagement.getCurrentWebDriver()).executeScript(js);
}
/**
* Execute the given JavaScript code asynchronously.
*
* The given code may contain multiple lines of code, but must contain a
* return statement (with the value to be returned) at the end.
*
* The given code may be divided into multiple cells in the test data. In
* that case, the parts are concatenated together without adding spaces. If
* the given code is an absolute path to an existing file, the JavaScript to
* execute will be read from that file. Forward slashes work as a path
* separator on all operating systems.
*
* Note that by default the code will be executed in the context of the
* Selenium object itself, so this will refer to the Selenium object.
* Use window to refer to the window of your application, e.g.
* window.document.getElementById('foo').
*
* Example:
*
*
* Execute Async JavaScript
* return window.my_js_function('arg1', 'arg2');
* # Directly execute the JavaScript
*
*
* Execute Async JavaScript
* ${CURDIR}/js_to_execute.js
* # Load the JavaScript to execute from file
*
*
*
* @param code
* The JavaScript code or a file name.
* @return The return value of the executed code.
*/
@RobotKeyword
@ArgumentNames({ "*code" })
public Object executeAsyncJavascript(String... code) {
String js = getJavascriptToExecute(Python.join("", Arrays.asList(code)));
String.format("Executing JavaScript:\n%s", js);
return ((JavascriptExecutor) browserManagement.getCurrentWebDriver()).executeAsyncScript(js);
}
/**
* Returns the text of current JavaScript alert.
*
* This keyword will fail if no alert is present. Note that following
* keywords will fail unless the alert is confirmed by the keywords 'Alert
* Should Be Present' or `Confirm Action`.
*
* @return The alert message.
*/
@RobotKeyword
public String getAlertMessage() {
try {
Alert alert = browserManagement.getCurrentWebDriver().switchTo().alert();
String text = alert.getText().replace("\n", "");
return text;
} catch (WebDriverException wde) {
throw new SeleniumLibraryNonFatalException("There were no alerts");
}
}
// ##############################
// Internal Methods
// ##############################
protected static String readFile(String path) throws IOException {
FileInputStream stream = new FileInputStream(new File(path));
try {
FileChannel fc = stream.getChannel();
MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
/* Instead of using default, pass in a decoder. */
return Charset.defaultCharset().decode(bb).toString();
} finally {
stream.close();
}
}
protected String getJavascriptToExecute(String code) {
String codepath = code.replace('/', File.separatorChar);
if (!new File(codepath).isFile()) {
return code;
}
logging.html(String.format("Reading JavaScript from file %s.",
codepath.replace(File.separatorChar, '/'), codepath));
try {
return readFile(codepath);
} catch (IOException e) {
throw new SeleniumLibraryNonFatalException("Cannot read JavaScript file: " + codepath);
}
}
}