What is the difference between WebDriver and WebElement in Selenium? - selenium

What is the difference between WebDriver and WebElement in Selenium?
Sample Code:
WebDriver driver = new FirefoxDriver();
driver.get("http://www.google.com");
WebElement s = driver.findElement(By.name("q"));
s.sendKeys("Packt Publishing");
s.submit();

WebDriver Interface
From Selenium's perspective, the What is the difference between ChromeDriver and WebDriver in selenium? interface is similar like a agreement which the 3rd party Browser Vendors like Mozilla, Chrome, Internet Explorer, Safari, etc have to adhere and implement the same. This would in-turn help the end-users to use the exposed APIs to write a common code and implement the functionalities across all the available browsers without any change.
WebDriver driver = new FirefoxDriver();
Through the line of code:
WebDriver driver = new FirefoxDriver();
We are creating an instance of the WebDriver Interface and casting it to FirefoxDriver class. All the Browser Drivers like FirefoxDriver, ChromeDriver, InternetExplorerDriver, PhantomJSDriver, SafariDriver etc implemented the WebDriver interface (actually the RemoteWebDriver class implements WebDriver Interface and the browser drivers extends RemoteWebDriver). So if we use WebDriver driver, then we can use the already initialized driver instance (as common object variable) for all browsers we want to automate e.g. Mozilla, Chrome, InternetExplorer, PhantomJS, Safari.
WebDriver driver = new FirefoxDriver();
driver = new ChromeDriver();
driver = new FirefoxDriver();
driver = new SafariDriver();
You can find a detailed discussion in:
Is this correct - FirefoxDriver driver = new FirefoxDriver();?
what is the difference between ChromeDriver and WebDriver in selenium?
WebElement Interface
From Selenium perspective, WebElement represents an HTML element. Generally, all the operations to do with interacting with a page will be performed through this interface.
A WebElement is an abstraction used to identify the Element nodes and are simply known as elements when it is transported via the protocol, between remote and local ends. The web element identifier is the string constant expressed as:
"element-6066-11e4-a52e-4f735466cecf"
You can find a detailed discussion in Values returned by webdrivers
Each element has an associated web element reference that uniquely identifies the element across all browsing contexts. The web element reference for every element representing the same element must be the same. It must be a string, and should be the result of generating a UUID.
An ECMAScript Object represents a web element if it has a web element identifier own property.
Each browsing context has an associated list of known elements. When the browsing context is discarded, the list of known elements is discarded along with it.
You can find a detailed discussion in Why return type of findElement(By by) is WebElement?
Some of the commonly used associated methods are as follows:
clear()
click()
findElement(By by)
findElements(By by)
getAttribute(java.lang.String name)
getCssValue(java.lang.String propertyName)
getLocation()
getRect()
getSize()
getTagName()
getText()
isDisplayed()
isEnabled()
isSelected()
sendKeys(java.lang.CharSequence... keysToSend)
submit()

The WebDriver class focuses on driving the browser in a broad sense. It loads pages, it switches to different windows/frames, gets the page title etc. Broad actions that aren't specific to an element on the page.
WebElement concentrates on interacting with a specific element that you've located. Things like:
Clicking that specific element
Retrieving text and other values from that specific element
Finding out where that specific element is positioned
Sending text to that specific element (like filling an input field)
The only real overlap between WebDriver and WebElement are the findElement and findElements methods. For Webdriver, these methods locate the given By anywhere on the page. For WebElement these methods locate the given By within the context of that element (inside it, generally).

Simple answer:
The WebDriver focuses on manipulating the browser.
The WebElement is just an Document element object like
<button></button>

Related

what is the Purpose of Remote webdriver between webdriver interface and chromedriver class

Search Context is the super most interface in selenium, which is extended by another interface called Web Driver.
-All the abstract methods of Search Context and Web Driver interfaces are implemented in Remote WebDriver class.
-All the browser related classes such as Firefox Driver, Chrome Driver etc., extends the Remote Webdriver class.
As per the above stmt How the remote web driver class can give the definition for all the abstract methods which defined in the search context interface and webdriver interface. because the implementation details are different specific with browser for the function driver.get/driver.title like that
why can not chromedriver or firefoxdriver class directly extend the webdriver interface. why remotedriver class kept in between webdriver interface and chromedriver/firefoxdriver/iedriver class
While the implementation may be different for each browser at the driver level (chromedriver.exe, geckodriver.exe, IEDriverServer.exe, etc.), the mechanism by which the language bindings execute the commands is the same for all browsers. So, while each browser-specific driver class could implement the interface directly, the code in each driver class would be identical. The use of RemoteWebDriver as a base class eliminates duplicated code. Additionally, the RemoteWebDriver class has the added benefit of being useful to execute WebDriver commands against a browser running on a different (remote) machine from the one where the language binding code is executing.
Moreover, the SearchContext interface defines two methods, findElement and findElements. The WebDriver interface isn’t the only one to extend it; WebElement does too. It’s perfectly valid to find an element child element of an already-located element. Consider the following example HTML fragment:
<div class="foo">
I don’t want to select this div.
</div>
<div class="bar">
I need to do something with this div.
<div class="foo">
But I also do need to select this div
</div>
</div>
Using driver.findElement(By.cssSelector("div.foo")) would give me the wrong element, the <div> I specifically do not want. However, I can do the following to get the proper element:
// Assume driver is a valid WebDriver instance
WebElement parent = driver.findElement(By.cssSelector("div.bar");
// Since WebElement also extends SearchContext,
// we can do this, which limits the scope of the
// find to only children of the parent element
WebElement child = parent.findElement(By.cssSelector("div.foo");
Now I can manipulate the exact element I want.

Interfaces in Selenium WebDriver

I want some interfaces used in selenium webDriver.
WebDriver itself is one of the interface. can we list down some more?
You can find list of all RemoteWebDriver implemented interfaces in the docs
All Implemented Interfaces:
HasCapabilities, HasInputDevices,
Interactive, FindsByClassName, FindsByCssSelector, FindsById,
FindsByLinkText, FindsByName, FindsByTagName, FindsByXPath,
JavascriptExecutor, SearchContext, TakesScreenshot, WebDriver
Webdriver itself is an interface. There are a couple of interfaces in Selenium. A few of them are as below:
Alert
Capabilities
ContextAware
HasCapabilities
JavascriptExecutor
OutputType
Rotatable
SearchContext
TakesScreenshot
WebDriver
WebDriver.ImeHandler
WebDriver.Navigation
WebDriver.Options
WebDriver.TargetLocator
WebDriver.Timeouts
WebDriver.Window
WebElement
WrapsDriver
WrapsElement
You can further refer to the Selenium Java docs for more info here

Automation testing using selenium WebDriver?

Selenium RC command selenium.waitForPageToLoad("30000") is not working in WebDriver.
Is there any alternate command for this in WebDriver?
There are two types of waits you can use in Selenium; implicit and explicit.
Below examples are written in Java:
1) Explicit Wait:
new WebDriverWait(super.getDriver(), 10).until(ExpectedConditions.elementToBeClickable(site_logo));
Above code will wait 10 seconds for site logo element to be clickable, if not it will throw an exception. ExpectedConditions class has bunch of other methods you can use. You can check whether an element is present or not etc...
2) Implicit Wait:
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
An implicit wait is to tell WebDriver to poll the DOM for a certain amount of time when trying to find an element or elements if they are not immediately available. The default setting is 0. Once set, the implicit wait is set for the life of the WebDriver object instance.
There is also Thread.sleep(Time in milliseconds); method, but I don't recommend you to use this one.
For more information: http://docs.seleniumhq.org/docs/04_webdriver_advanced.jsp
You can use WebDriveWait to solve it:
http://docs.seleniumhq.org/docs/04_webdriver_advanced.jsp
For waiting to an element, use wait.until(ExpectedConditions.visibilityOfElementLocated) :
#Test
public void test1() throws Exception {
WebDriverWait wait = new WebDriverWait(driver, 1);
driver.get("example.html");
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(elementLocation)));
driver.close();
}

Access new window elements through selenium RC

I am new to Selenium. This is my first attempt. And I want to access the Elements in the new window through Selenium RC. I have a page with a hyper link clicking on it will open new page. I want to enter username and password elements in the new window. Html Code is
Employee Login
and the new page elements are "emailAddress" and "password" for login.
My selenium code is
public static void main(String args[]) throws Exception
{
RemoteControlConfiguration rc=new RemoteControlConfiguration();
rc.setPort(2343);
SeleniumServer se= new SeleniumServer(rc);
Selenium sel=new DefaultSelenium("localhost",2343,"*firefox","http://neo.local/");
se.start();
sel.start();
sel.open("/");
sel.windowMaximize();
//sel.wait(1000);
sel.click("empLogin");
//sel.wait(2000);
//sel.openWindow("http://myneo.neo.local/user/login", "NewNeo");
//sel.waitForPopUp("NewNeo", "1000");
//sel.selectWindow("id=NewNeo");
Thread.sleep(20000);
sel.type("emailAddress", "kiranxxxxx#xxxxxx.com");
sel.type("password", "xxxxxxxx");
}
First I tried with normal approach, where it failed to identify the elements. Then I tried with open window and selectWindow options, where it through errors like
"Exception in thread "main" com.thoughtworks.selenium.SeleniumException: ERROR: Window locator not recognized: id
at com.thoughtworks.selenium.HttpCommandProcessor.throwAssertionFailureExceptionOrError(HttpCommandProcessor.java:109)
at com.thoughtworks.selenium.HttpCommandProcessor.doCommand(HttpCommandProcessor.java:103)
at com.thoughtworks.selenium.DefaultSelenium.selectWindow(DefaultSelenium.java:377)
at Demo.main(Demo.java:24)"
Some one told me that it is not possible with Selenium RC. It can achieved through Selenium Webdriver only. Is it true?
Please Help,
Thanks in Advance.
Selenium RC is not maintained anymore, I would recommend you to use WebDriver instead. Selenium RC is a Javascript application where as WebDriver uses browsers Native API. Therefore browser interactions using WebDriver are close to what the real user does. Also WebDriver's API is more intuitive and easy to use in my opinion. I don't see HTML in your question, but you could do start with something like this,
WebDriver driver = new FirefoxDriver();
WebElement login = driver.findElement(By.id("empLogin"));
login.click();
I will say, do as #nilesh stated. Use Selenium WebDriver.
Answer to your specific problem though:
You are failing at this line because you are not specifying a selector strategy.
sel.click("empLogin");
If the id attribute is empLogin then do
sel.click("id=empLogin");
There are other selector strategies you can use:
css=
id=
xpath=
link=
etc...
You can see the full list here.
You will also fail here due to the same issue:
sel.type("emailAddress", "kiranxxxxx#xxxxxx.com");
sel.type("password", "xxxxxxxx");
Put a selector strategy prefix before those fields.
sel.type("name=emailAddress", "kiranxxxxx#xxxxxx.com");
sel.type("name=password", "xxxxxxxx");

Selenium clicking a button

I am trying out selenium for the 1st time and I have a quick question. When I call the click() method on a WebElement, I noticed that it is a void type method. So does the HtmlUnitDriver hold the updated page that is rendered after the click() happens?
Yes. The WebDriver interface is controlling the browser, however it's still the browser (in your case, HtmlUnit) that does most of the work and remembers the state of teh page etc.
Therefore, WebDriver as such doesn't really have a state (an overly simplified statement, but true for your purpose). When you send a click() command, it performs it in the browser, than waits for the browser to complete its job (load the new page), then again waits for your commands on the new page.
WebDriver always operates on what the browser currently has.
I can see from your question that you are using HtmlUnitDriver. JavaScript is disabled in this driver by default (for explanation click here). This driver uses the Rhino JavaScript engine and is not used in any of the popular browsers. This might explain why the actions you are trying work fine in Firefox but not in Selenium.
You could try enabling JavaScript in HtmlUnit as follows:
HtmlUnitDriver driver = new HtmlUnitDriver();
driver.setJavascriptEnabled(true);
But instead I would recommend using FirefoxDriver.
WebDriver driver = new FirefoxDriver();
This should emulate the behavior you're seeing when you navigate through the webpages yourself.