I am super confused with selenium.
Completely new to automated testing and struggling to get a foothold with selenium.
http://www.seleniumhq.org/projects/webdriver/
I get the concept of writing tests and have done a few with in angular with protractor, but i need to use selenium for a particular project and not sure where to start.
To start with I just want to be able to write some simple client side tests, but i have no idea where to start with on Selenium, i read their docs but not really any the wiser..
A webdriver test is just a script, written in one of many compatible languages (java, python, etc). The script runs on any machine. During development it will typically run on your local machine, but eventually your test could run on a continuous integration server.
Webdriver has two modes of operation: it can open a browser on the same machine that the script is running, or it can send a request to a selenium grid hub, which will open a browser on one of its nodes.
As a simple example, here is a complete working example of a selenium test in python (taken from python selenium bindings Getting Started page):
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Firefox()
driver.get("http://www.python.org")
assert "Python" in driver.title
elem = driver.find_element_by_name("q")
elem.send_keys("pycon")
elem.send_keys(Keys.RETURN)
assert "No results found." not in driver.page_source
driver.close()
If you have python and the selenium libraries installed, you can save this file to "example_test.py" and then run it from a command prompt with python example_test.py
Here's a similar test, this one in javascript, taken from the WebDriverJS User's Guide. You would run it the same way you run any javascript program.
var webdriver = require('selenium-webdriver');
var driver = new webdriver.Builder().
withCapabilities(webdriver.Capabilities.chrome()).
build();
driver.get('http://www.google.com');
driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
driver.findElement(webdriver.By.name('btnG')).click();
driver.wait(function() {
return driver.getTitle().then(function(title) {
return title === 'webdriver - Google Search';
});
}, 1000);
driver.quit();
To give you an organic answer to your question, when you run a selenium Firefox browser test, it starts a local ad-hoc "Selenium grid hub listener" on a port like 30005 or something at the start of the test. Then, the code that you write talks to that local port in JSON format by sending local http requests to localhost:30005 . The "Grid hub" listening on that port knows how to talk to your local web browser and controls it by answering commands passed through that port. At the end of the test, the "selenium grid hub listener port" closes.
If you do some reading and try to understand how the "Selenium Grid Hub" works and also learn about "WebDriver Wire Protocol", then it might help you start understanding what I explained above.
Always read the official Selenium docs for references, but if you are using Java, you can get a head-start by using the Conductor framework
It's a Java specific DSL, so won't work with any other.
A test would look like this:
#Config(url="http://google.com", browser=Browsers.CHROME)
public class MyTest {
#Test
public void testGoogle() {
// a quick google search
setText(By.name("q"), "something")
.click("[name='btnG']");
}
}
Related
Beginner on selenium grid, I just created a small test that allows to navigate on the home page of stackoverflow
For this I placed the selenium server on my disk, I opened 2 terminals as shown in the documentation here.
https://www.selenium.dev/documentation/grid/getting_started/#hub-and-nodes
The test starts well, and now I would like to run the same test under firefox while modifying the OS (for example: windows). How do I do this? Do I have to create another test file in my project? And then how to run the test with multiple configurations? I can’t find an answer to these questions.
My configuration:
-Linux Ubuntu 20.04
-Google and chrome 95
-the last version selenium server : 4.1.1
Here's the code of the test:
public class StepGoStackoverflow {
RemoteWebDriver driver;
String nodeUrl;
#Given("I'm on google search page")
public void i_m_on_google_search_page() {
try {
nodeUrl = "http://localhost:4444";
ChromeOptions options = new ChromeOptions();
// options.addArguments("--headless");
options.addArguments("start-maximized");
driver = new RemoteWebDriver(new URL(nodeUrl), options);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
driver.get("https://www.google.com");
} catch (MalformedURLException error) {
error.printStackTrace();
}
}
#When("I enter the name of the site")
public void i_enter_the_name_of_the_site() {
WebElement webElementList = driver.findElement(By.id("L2AGLb"));
webElementList.click();
driver.findElement(By.name("q")).sendKeys("stackoverflow", Keys.ENTER);
}
#Then("I'm navigated on the home page of stackoverflow")
public void i_m_navigated_on_the_home_page_of_stackoverflow() {
driver.findElement(By.xpath("//a[#href='https://stackoverflow.com/']")).click();
driver.close();
}
}
EDIT:
I forgot to give the snipet of Gerkhin:
Feature: search the home page of stackoverflow
Scenario: Go to the site stackoverflow
Given I'm on google search page
When I enter the name of the site
Then I'm navigated on the home page of stackoverflow
Thank you
I can see that you are using Cucumber so I edited your question to add corresponding tag (since that matters as we're taking about parameterization).
Grid part
The idea of the Selenium Grid is that you install Grid components at a cluster where the nodes represent different OSs and each runtime/OS has one or more drivers and browsers installed.
So you configure nodes so that they know where are drivers installed and how to run browsers (and what browser can each node execute: e.g. Chrome, Firefox) and each node registers at the grid component called hub.
On one side a hub knows which nodes are running at which OS and what browsers they can operate with. On another hand hub acts as remote web driver (it exposes webdriver protocol to external clients aka automated tests).
You can find an overview of the grid here and find configuration flags and aspects here.
Code part
On the code side you parameterize your tests so that each test is executed from scratch but with different capabilities set up. In your example you only use ChromeOptions which would make hub to dispatch your calls to a node that can run Chrome browser.
Your challenge is to make your code configure different capabilities each run so that Grid will look up appropriate node in the cluster for your test (like "ah-ha.. you want to run Firefox on Linux which means I'll dispatch your calls to node C")
Cucumber
Since you are using Cucumber in your example I assume that you tend to incorporate it into final solution. If so, you need to start from learning parameterization practices in cucumber: See here, here and here; setting up context in Cucumber, and sharing the state in Cucumber with Dependency Injection with Guice or PicoContainer.
Combine everything, add a handful of parallelization and you will gain the most value from your framework.
Why is the code //RemoteWebDriver driver= new FirefoxDriver(); not used instead of //WebDriver driver= new FirefoxDriver() to create a driver object?
I feel that RemoteWebDriver gives more capabilities for the driver instance than webdriver reference. Can someone clarify this?
WebDriver will start up a web browser on the computer where the code instantiates it. For example. If you write a bit of code, and then run it to see how you are doing, the browser will pop up on your screen and you will see WebDriver begin to manipulate that web browser window (if everything went well!)
With a major exception which I will explain below, RemoteWebDriver will do the same thing; it will open and manipulate a browser window (if everything went well!) Generally speaking, You can actually switch the instatiation of a WebDriver with a RemoteWebDriver (well, there are advanced cases where you might not be able too do this) The major difference is that RemoteWebDriver sends that request to open and control a web browser to a server, so you normally wouldn’t see the browser open and do it’s thing.
Selenium server is the program that runs and waits for RemoteWebDriver connections. You can run it on your local computer to test it out. If you get it set up and running, you’ll be able to create a RemoteWebDriver and see that the Selenium server accepts the connection and allows you to control the web browser window.
The gains from using RemoteWebDriver?
If you can do connect to a local Selenium server, you can be confident that you have the knowledge and skills needed to connect to a remote Selenium server, or even to a paid service like SauceLabs (Hosting Selenium for you) that allows you to run lots of tests on lots of OS’s and lots of browsers without having to actually maintain or install any of them (Linux, Windows 8, Windows 10, MacOS, Andriod, IOS, IE, Firefox, Opera, Safari, Firefox Mobile, etc) You’ll want to look into running tests asynchronously at this point. You don’t have to run them one at a time, so can test a large number of OS/Browser variations in a very short time.
What does it mean when something is used only for client/server communication?
When you uses a Selenium grid with have one hub and multiple clients, you invoke RemoteWebDriver through which you instantiate the server and and make the request to it.
WebDriver is an interface in selenium which extends SearchContext interface (super most interface in selenium)
Where as RemoteWebdriver is a class which implements WebDriver,
We can use RemoteWebdriver, when we going to execute the test in romote environment,(selenium grid).
WebDriver interface will invoke the driver locally,
Currently in automation mostly we are using WebDriver only.
Grid not using widely.
WebDriver driver=new ChromeDriver() ;
driver is the reference variable where used to access chromedriver class.
Using driver instance we can access all the unimplemented methods available in WebDriver interface, also able to access all the properties available in chromedriver class.
For more details
https://www.softwaretestingmaterial.com/webdriver-driver-new-firefoxdriver/
I would like to make it clear about the difference between protractor VS ghostdriver.
With protractor:
start selenium web server for testing.
multiple browser testing.
whenever it start testing, it open the browser.
With ghostdriver:
start phantomjs web server.
can be config multiple browser too.
can run separate with selenium or integrate with selenium.
My question is PhantomJS webdriver can run alone without selenium webdriver, multiple browsers and good for CI. Why do we need to run selenium and integrate selenium with phantomjs using ghostdriver?
While I'm not entirely sure I understand your question, I'll take a stab at answering it. With WebDriver, driving a browser is done via a standardized JSON-over-HTTP wire protocol. This means that you need a "server" component that understands the wire protocol to drive any particular browser. For each of the major desktop browsers (Internet Explorer, Chrome, and Firefox), there is a server component that your WebDriver code talks to (IEDriverServer.exe, chromedriver.exe, or a Firefox browser extension, respectively). PhantomJS also implements a server component that understands the WebDriver wire protocol, so the same high-level WebDriver code can be used with PhantomJS that is used with other browsers. Note that the Selenium server is not required to drive any of the browsers on the local machine.
Now, since the protocol used is simply transmitted over HTTP, that gives WebDriver the opportunity to run the WebDriver code on one machine, while driving a browser located on an entirely different machine. That's where the Selenium server comes in. The Selenium server starts an HTTP server that understands the WebDriver JSON wire protocol. When that server receives a WebDriver command, it can forward that command to another "server" component, either running on that machine (as a standalone remote server), or on yet another machine running another instance of the Selenium server (in a "grid" configuration).
So to answer your question, yes, WebDriver code can be executed against PhantomJS without using the Selenium server. It can likewise be executed against Internet Explorer, Firefox, Chrome, Safari, and some versions of Opera, all without using the Selenium server. Notice that all of this is true without mentioning Protractor at all. Since Protractor is based on WebDriverJS, as long as there's a "server" component running, whether that's a Selenium server, chromedriver.exe, IEDriverServer.exe, or PhantomJS, the driver should be able to communicate with and drive that browser. Looking at the code, it appears that WebDriverJS (and, by extension, Protractor), should be able to execute against Chrome and PhantomJS without requiring the Selenium server, but I don't know enough about Protractor's wrapping of WebDriverJS to speak with authority.
I am trying to scrape a website that contains images using a headless Selenium.
Initially, the website populates 50 images. If you scroll down more and more images are loaded.
Windows 7 x64
python 2.7
recent install of selenium
[1] Non-Headless
Navigating to the website with selenium as follows:
from selenium import webdriver
browser = webdriver.Firefox()
browser.get(url)
browser.execute_script('window.scrollBy(0, 10000)')
browser.page_source
This works (if anyone has a better suggestion please let me know).
I can continue to scrollBy() until I reach the end and then pull the source page.
[2] Headless with HTMLUNIT
from selenium import webdriver
driver = webdriver.Remote(desired_capabilities=webdriver.DesiredCapabilities.HTMLUNIT)
driver.get(url)
I cannot use scrollBy() in this headless environment.
Any suggestions on how to scrape this kind of page?
Thanks
One option is to study the JavaScript to see how it calculates what to load next. Then implement that logic in your scraping client instead. Once you have done that, you can use faster scraping tools like Perl's WWW::Mechanize.
You need to enable JavaScript explicitly when using the HtmlUnit Driver:
driver.setJavascriptEnabled(true);
According to [http://code.google.com/p/selenium/wiki/HtmlUnitDriver](the docs), it should emulate IE's JavaScript handling by default.
When I tried the same method, I got error messages that selenium crashed while connecting java to simulate javascript.
I wrote the script into execute_script method then the code works well.
I guess the communication between selenium and java server part is not configured properly.
Enabling the javascript with HTMLUNITDRIVERWITHJS is possible and quick ;)
I'm not sure I quite understand the difference. WebDriver API also directly controls the browser of choice. When should you use selenium remote control (selenium RC) instead ?
Right now, my current situation is I am testing a web application by writing a suite with Selenium WebDriver API and letting it run on my computer. The tests are taking longer and longer to complete, so I have been searching for ways to run the tests on a Linux server.
If I use Selenium Remote Control, does this mean I have to rewrite everything I wrote with WebDriver API?
I am getting confused with Selenium Grid, Hudson, Selenium RC. I found a Selenium Grid plugin for Hudson, but not sure if this includes Selenium RC.
Am I taking the correct route? I envision the following architecture:
Hudson running on few Ubuntu dedicated servers.
Hudson running with Xvnc & Selenium Grid plugin. (Do I need to install Firefox separately ?)
Selenium grid running selenium RC test suites.
I think this is far more time efficient than running test on my current working desktop computer with WebDriver API.
WebDriver is now Selenium 2. The Selenium and WebDriver code bases are being merged. WebDriver gets over a number of issues that Selenium has and Selenium gets over a number of issues that Webdriver has.
If you have written your tests in Selenium one you don't have to rewrite them to work with Selenium 2. We, the core developers, have written it so that you create a browser instance and inject that into Selenium and your Selenium 1 tests will work in Selenium 2. I have put an example below for you.
// You may use any WebDriver implementation. Firefox is used here as an example
WebDriver driver = new FirefoxDriver();
// A "base url", used by selenium to resolve relative URLs
String baseUrl = "http://www.google.com";
// Create the Selenium implementation
Selenium selenium = new WebDriverBackedSelenium(driver, baseUrl);
// Perform actions with selenium
selenium.open("http://www.google.com");
selenium.type("name=q", "cheese");
selenium.click("name=btnG");
Selenium 2 unfortunately has not been put into Selenium 2 but it shouldn't be too long until it has been added since we are hoping to reach beta in the next couple of months.
As far as I understand, Webdriver implementation started little later than Selenium RC. From my point of view, WebDriver is more flexible solution, which fixed some annoying problems of SeleniumRC.
WebDriver provides standard interface for testing web GUI. There are several implementations of this interface (HTTP, browser-specific and based on Selenium). Since you already have some WebDriver tests, you must be familiar with basic docs like this
The tests are getting longer and longer to complete, so I have been searching for ways to run the tests on a linux server.
Did you try to find actual bottlenecks? I'm not sure, that elimination of WebDriver layer will help. I think, most time is spent on Selenium commands sending and HTTP requests to system-under-test.
If I use sleneium remote control, does
this mean I have to rewrite everything
I wrote with WebDriver API ?
Generally, yes. If you did not implement some additional layer between tests code and WebDriver.
As for Selenium Grid:
You may start several Selenium RC instances on several different [virtual] nodes, then register them in Selenium Grid. Your tests connect to Selenium Grid, and it redirects all commands to SeleniumRC instances, coordinating them in accordance with required browsers.
For details of hudson plugin you may find more info here