How to use webdriver using the dart library? - automation

I am having trouble getting started with the webdriver dart library.
I was hoping for some simple examples.
I do have the seleniumn server standalone running in the background.
I am very new to dart and very experienced with ruby and watir-webdriver.
I was expecting something similar to the code below
import 'package:webdriver/webdriver.dart';
main() {
var url = "http://google.com";
var driver = new WebDriver();
b = driver.newSession(browser:'firefox');
b.getUrl(url);
}
But the error I am getting is
Unhandled exception:
No constructor 'WebDriver' declared in class 'WebDriver'.
Looking at the source
class WebDriver extends WebDriverBase {
WebDriver(host, port, path) : super(host, port, path);
So it seems like the constructor is there; and the defaults are in the WebDriverBase to go to the remote server. What am I doing wrong? I have scoured the internet trying to find simple examples with no luck

Currently, there are known issues with local and session storage, script execution, and log access.
To use these bindings, the Selenium standalone server must be running. You can download it at http://code.google.com/p/selenium/downloads/list.
There are a number of commands that use ids to access page elements. These ids are not the HTML ids; they are opaque ids internal to WebDriver. To get the id for an element you would first need to do a search, get the results, and extract the WebDriver id from the returned Map using the 'ELEMENT' key. see http://commondatastorage.googleapis.com/dartlang-api-docs/13991/webdriver.html

Related

sendDevToolsCommand in Selenium 4 alpha

According to this article, Selenium 4 alpha has a sendDevToolsCommand that sends an arbitrary DevTools command to the browser and returns a promise that will be resolved when the command has finished:
Added “sendDevToolsCommand” and “setDownloadPath” for chrome.Driver.
But I can't seem to find how to use it. It sounds a bit like using JavaScript executor in Selenium.
Can someone provide an example usage? I'm using Selenium + Java.
The command to call the devtool api was added a few years back in the Chrome driver.
You can already use it with Selenium even if the method is not yet present:
Take full page screenshot
Print To PDF
Inject some Javascript before the page loads
Block a network URL
Save/restore the cookies for all domains
Get transparent screenshot
This command gives you access to the devtools api, which is used by ChromeDriver internally to drive the browser.
The method takes the name of the command as first argument and a dictionary of parameters as second argument. To figure out how to call a command, add puppeteer in your searches. For instance puppeteer set download location.
Note that executeCdpCommand is implemented in the Java master branch, so it should be available in the next release.
I couldn't find the sendDevToolsCommand in the Selenium documentation yet, but the source actually has the setDownloadPath that you also mentioned above defined right below, which actually uses the sendDevToolsCommand. Based on that usage, it seems like you could do something like:
const { Builder } = require("selenium-webdriver");
const driverInstance = await new Builder()
.withCapabilities({ browserName: "chrome" })
.build();
driverInstance.sendDevToolsCommand('Page.setDownloadBehavior', {
behavior: 'allow',
downloadPath: path
})
or for a visually obvious example:
await driverInstance.sendDevToolsCommand("Emulation.setDefaultBackgroundColorOverride", {
color: { r: 0, g: 255, b: 0, a: 1 } // watch out, it's bright!
});
where the first argument is a Chrome Devtools Protocol Domain method (e.g. or Page.setDownloadBehavior or Emulation.setCPUThrottlingRate) and the second argument is an object containing the options for that Domain method (as described in the same protocol docs).
Edit: just tested and the above works :)
I'm excited that this was added because it means that, in addition to network throttling, it should be pretty trivial to add cpu throttling to Selenium tests now! Something like:
driverInstance.sendDevToolsCommand('Emulation.setCPUThrottlingRate', {
rate: 4 // throttle cpu 4x
}
Selenium 4 release will have a user friendly API for Chrome DevTools protocol.
I just finished implementing Network and Performance domains for the Selenium Java client.
https://github.com/SeleniumHQ/selenium/pull/7212
In addition, there is a generic API for all domains in Java client that was merged a while ago.
All those new features will be released probably in the next Alpha release.

Set parameter to JUnit5 extension

I wonder how to configure an extension by a test.
Scenario:
The test provides a value that should be used inside the extension.
Current Solution:
The value is defined as field inside the test and used by the extension thru scanning all declared fields and pick the correct one (reflection).
Problem:
This solution is very indirect. People using this extension must know about extension internals and declare the correct fields (type and value). Errors can lead the developer into the right direction, but its a bit of pain by try/error.
Is there a way to use e.g. annotation with value to configure a junit5 extension?
You may either provide configuration parameters and access them via the ExtensionContext at runtime or since 5.1 there's a programmatic way to register customized extension instances via #RegisterExtension.
Example copied from the JUnit 5 User-Guide:
#RegisterExtension
static WebServerExtension server = WebServerExtension.builder()
.enableSecurity(false)
.build();
#Test
void getProductList() {
WebClient webClient = new WebClient();
String serverUrl = server.getServerUrl();
// Use WebClient to connect to web server using serverUrl and verify response
assertEquals(200, webClient.get(serverUrl + "/products").getResponseStatus());
}

Logging Messages from Java Class back to the Karate Report

We have a scenario where we have to post a json request and then validate few actions in the UI. So we have a karate feature file which hits a request and after that we are invoking a java class from within the feature file. The java class would run the Selenium Webdriver test of us. In the java methods we have few Assertions/Info Messages which we would like to log back to the Karate Reports.
Is there a way in Karate with which we can write these messages from my Java Class to the Karate Test Reports?
If you use the Karate parallel runner it is designed to collect anything logged to package com.intuit.karate, which will then appear in the cucumber-html-report.
So you can try using the same slf4j Logger - and it might work.
A better way might be to just return a Map back to Karate from your Java code, with all the information you need to log. Then all you need to do is use the print keyword. I would recommend this approach actually, it should be less complicated and it does not assume that you are using the Cucumber HTML reporting. You could even do Karate asserts with the match keyword on the JSON that you get, refer to this example: dogs.feature.
We did try logging back to “com.intuit.karate” as shown below and its logging to the ‘overview-features.html’ report
Logger in Java class :
private static final Logger logger = LoggerFactory.getLogger("com.intuit.karate");
However we made an observation that if an exception is thrown from the java class the exception would appear first and then followed by all the information that is logged, both looks to exist as a different piece in the report.
For e.g
This is sample method with logger in the java class which i am invoking from the feature file
public void myTestMethod() {
logger.info("Starting Test");
logger.info("Setting path of chrome driver");
System.setProperty("webdriver.chrome.driver", "chromedriver.exe"); //driver doesnt exist in this path
logger.info("invoking chrome"); // we would expect the exception to be thrown after this line
driver = new ChromeDriver();
logger.info("perform search in google");
driver.get("http://www.google.com");
driver.findElement(By.id("lst-ib")).sendKeys("Selenium");
driver.findElement(By.id("lst-ib")).submit();
driver.quit();
}
But in the reports the exception appears first and then all the information that is logged from the java class. Both looks like two different pieces in the report, please see the report here https://www.screencast.com/t/bBhAIj7WKj
In the above case would it be possible to have the exception thrown after the line where we log” invoking Chrome” i think this would make it easier to identify the test failures from the reports. Please let us know if this would be possible
It worked for me by passing the karate object from the javascript file to the java code. With this I was able to call the karate.log function from the Java code. This way I could see the messages on the report.

Selenium Grid Proxy: how to get the response after a command get executed

I created a Selenium Grid proxy, I want to log every command done, the problem is I can't find a way to get the response of the command for example after "GetTitle" command I want to get the "Title" returned.
Where do you want this logging to be done ? If you attempt at logging this at the Custom Proxy, then these logs would be available only on the machine that runs the hub. Is that what you want ? If yes, then here's how you should be doing it :
Within an overloaded variant of org.openqa.grid.internal.listeners.CommandListener#afterCommand (this method should be available in your DefaultRemoteProxy extension object that you are building), extract this information from within the javax.servlet.http.HttpServletRequest by reading its entity value and then translating that into a proper payload.
Here's how the afterCommand() (or) beforeCommand() method from your customized version of org.openqa.grid.selenium.proxy.DefaultRemoteProxy can look like:
org.openqa.grid.web.servlet.handler.SeleniumBasedResponse ar = new org.openqa.grid.web.servlet.handler.SeleniumBasedResponse(response);
if (ar.getForwardedContent() != null) {
System.err.println("Content" + ar.getForwardedContent());
}
If that's not what you want, then you should be looking at leveraging the EventFiringWebDriver. Take a look at the below blogs to learn how to work with the EventFiringWebDriver. The EventFiringWebDriver does not require customization at the Grid side, it just needs you to make use of the EventFiringWebDriver which would wrap within it an existing RemoteWebDriver object and the listeners you inject to it will help you get this.
http://darrellgrainger.blogspot.in/2011/02/generating-screen-capture-on-exception.html
https://rationaleemotions.wordpress.com/2015/04/18/eavesdropping-into-webdriver/ (This is my blog) Here I talk about not even using EventFiringWebDriver but instead work with a decorated CommandExecutor which would log all these information for you.

Unable to inject javascript using selenium 3 in firefox

I am injecting java script variables using selenium and retrieving it for verification.
Below is my sample code, which was working fine with selenium version 2.53.1.
When I upgraded to selenium 3 and started to use gecko driver for firefox, it throws exception when I am retrieving value.
driver.executeScript("globalVar='Amit';");
Object result = driver.executeScript("return globalVar");
System.out.println(result.toString());
Exception:
org.openqa.selenium.JavascriptException: ReferenceError: globalVar is not defined
In selenium 3 same code also working for Chrome.
Am I missing anything here? Or is there any capabilities added to allow such things in Firefox/Gecko driver?
The variables you set in a script that you execute are not global - they are "sitting" in the scope of the executed function. If you want to have a global variable that you want to access across multiple executed scripts, you have to use one of the available global objects, e.g. window:
driver.executeScript("window.globalVar = 'Amit';");
Object result = driver.executeScript("return window.globalVar");
System.out.println(result.toString());