This is the multi-page printable view of this section. Click here to print.
Additional features
1 - Working With Colors
You will occasionally want to validate the colour of something as part of your tests; the problem is that colour definitions on the web are not constant. Would it not be nice if there was an easy way to compare a HEX representation of a colour with a RGB representation of a colour, or a RGBA representation of a colour with a HSLA representation of a colour?
Worry not. There is a solution: the Color class!
First of all, you will need to import the class:
import org.openqa.selenium.support.Color;
from selenium.webdriver.support.color import Color
// This feature is not implemented - Help us by sending a pr to implement this feature
include Selenium::WebDriver::Support
// This feature is not implemented - Help us by sending a pr to implement this feature
import org.openqa.selenium.support.Color
You can now start creating colour objects. Every colour object will need to be created from a string representation of your colour. Supported colour representations are:
private final Color HEX_COLOUR = Color.fromString("#2F7ED8");
private final Color RGB_COLOUR = Color.fromString("rgb(255, 255, 255)");
private final Color RGB_COLOUR = Color.fromString("rgb(40%, 20%, 40%)");
private final Color RGBA_COLOUR = Color.fromString("rgba(255, 255, 255, 0.5)");
private final Color RGBA_COLOUR = Color.fromString("rgba(40%, 20%, 40%, 0.5)");
private final Color HSL_COLOUR = Color.fromString("hsl(100, 0%, 50%)");
private final Color HSLA_COLOUR = Color.fromString("hsla(100, 0%, 50%, 0.5)");
HEX_COLOUR = Color.from_string('#2F7ED8')
RGB_COLOUR = Color.from_string('rgb(255, 255, 255)')
RGB_COLOUR = Color.from_string('rgb(40%, 20%, 40%)')
RGBA_COLOUR = Color.from_string('rgba(255, 255, 255, 0.5)')
RGBA_COLOUR = Color.from_string('rgba(40%, 20%, 40%, 0.5)')
HSL_COLOUR = Color.from_string('hsl(100, 0%, 50%)')
HSLA_COLOUR = Color.from_string('hsla(100, 0%, 50%, 0.5)')
// This feature is not implemented - Help us by sending a pr to implement this feature
HEX_COLOUR = Color.from_string('#2F7ED8')
RGB_COLOUR = Color.from_string('rgb(255, 255, 255)')
RGB_COLOUR = Color.from_string('rgb(40%, 20%, 40%)')
RGBA_COLOUR = Color.from_string('rgba(255, 255, 255, 0.5)')
RGBA_COLOUR = Color.from_string('rgba(40%, 20%, 40%, 0.5)')
HSL_COLOUR = Color.from_string('hsl(100, 0%, 50%)')
HSLA_COLOUR = Color.from_string('hsla(100, 0%, 50%, 0.5)')
// This feature is not implemented - Help us by sending a pr to implement this feature
private val HEX_COLOUR = Color.fromString("#2F7ED8")
private val RGB_COLOUR = Color.fromString("rgb(255, 255, 255)")
private val RGB_COLOUR_PERCENT = Color.fromString("rgb(40%, 20%, 40%)")
private val RGBA_COLOUR = Color.fromString("rgba(255, 255, 255, 0.5)")
private val RGBA_COLOUR_PERCENT = Color.fromString("rgba(40%, 20%, 40%, 0.5)")
private val HSL_COLOUR = Color.fromString("hsl(100, 0%, 50%)")
private val HSLA_COLOUR = Color.fromString("hsla(100, 0%, 50%, 0.5)")
The Color class also supports all of the base colour definitions specified in http://www.w3.org/TR/css3-color/#html4.
private final Color BLACK = Color.fromString("black");
private final Color CHOCOLATE = Color.fromString("chocolate");
private final Color HOTPINK = Color.fromString("hotpink");
BLACK = Color.from_string('black')
CHOCOLATE = Color.from_string('chocolate')
HOTPINK = Color.from_string('hotpink')
// This feature is not implemented - Help us by sending a pr to implement this feature
BLACK = Color.from_string('black')
CHOCOLATE = Color.from_string('chocolate')
HOTPINK = Color.from_string('hotpink')
// This feature is not implemented - Help us by sending a pr to implement this feature
private val BLACK = Color.fromString("black")
private val CHOCOLATE = Color.fromString("chocolate")
private val HOTPINK = Color.fromString("hotpink")
Sometimes browsers will return a colour value of “transparent” if no colour has been set on an element. The Color class also supports this:
private final Color TRANSPARENT = Color.fromString("transparent");
TRANSPARENT = Color.from_string('transparent')
// This feature is not implemented - Help us by sending a pr to implement this feature
TRANSPARENT = Color.from_string('transparent')
// This feature is not implemented - Help us by sending a pr to implement this feature
private val TRANSPARENT = Color.fromString("transparent")
You can now safely query an element to get its colour/background colour knowing that any response will be correctly parsed and converted into a valid Color object:
Color loginButtonColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("color"));
Color loginButtonBackgroundColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("background-color"));
login_button_colour = Color.from_string(driver.find_element(By.ID,'login').value_of_css_property('color'))
login_button_background_colour = Color.from_string(driver.find_element(By.ID,'login').value_of_css_property('background-color'))
// This feature is not implemented - Help us by sending a pr to implement this feature
login_button_colour = Color.from_string(driver.find_element(id: 'login').css_value('color'))
login_button_background_colour = Color.from_string(driver.find_element(id: 'login').css_value('background-color'))
// This feature is not implemented - Help us by sending a pr to implement this feature
val loginButtonColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("color"))
val loginButtonBackgroundColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("background-color"))
You can then directly compare colour objects:
assert loginButtonBackgroundColour.equals(HOTPINK);
assert login_button_background_colour == HOTPINK
// This feature is not implemented - Help us by sending a pr to implement this feature
assert(login_button_background_colour == HOTPINK)
// This feature is not implemented - Help us by sending a pr to implement this feature
assert(loginButtonBackgroundColour.equals(HOTPINK))
Or you can convert the colour into one of the following formats and perform a static validation:
assert loginButtonBackgroundColour.asHex().equals("#ff69b4");
assert loginButtonBackgroundColour.asRgba().equals("rgba(255, 105, 180, 1)");
assert loginButtonBackgroundColour.asRgb().equals("rgb(255, 105, 180)");
assert login_button_background_colour.hex == '#ff69b4'
assert login_button_background_colour.rgba == 'rgba(255, 105, 180, 1)'
assert login_button_background_colour.rgb == 'rgb(255, 105, 180)'
// This feature is not implemented - Help us by sending a pr to implement this feature
assert(login_button_background_colour.hex == '#ff69b4')
assert(login_button_background_colour.rgba == 'rgba(255, 105, 180, 1)')
assert(login_button_background_colour.rgb == 'rgb(255, 105, 180)')
// This feature is not implemented - Help us by sending a pr to implement this feature
assert(loginButtonBackgroundColour.asHex().equals("#ff69b4"))
assert(loginButtonBackgroundColour.asRgba().equals("rgba(255, 105, 180, 1)"))
assert(loginButtonBackgroundColour.asRgb().equals("rgb(255, 105, 180)"))
Colours are no longer a problem.
2 - File Upload
The file upload dialog could be handled using Selenium, when the input element is of type file. An example of it, could be found on this web page- https://the-internet.herokuapp.com/upload We will require to have a file available with us, which we need to upload. The code to upload the file for different programming languages will be as follows -
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import io.github.bonigarcia.wdm.WebDriverManager;
class fileUploadDoc{
public static void main(String[] args) {
WebDriverManager.chromedriver().setup();
WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("https://the-internet.herokuapp.com/upload");
//we want to import selenium-snapshot file.
driver.findElement(By.id("file-upload")).sendKeys("selenium-snapshot.jpg");
driver.findElement(By.id("file-submit")).submit();
if(driver.getPageSource().contains("File Uploaded!")) {
System.out.println("file uploaded");
}
else{
System.out.println("file not uploaded");
}
driver.quit();
}
}
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
driver = webdriver.Chrome(ChromeDriverManager().install())
driver.implicitly_wait(10)
driver.get("https://the-internet.herokuapp.com/upload");
driver.find_element(By.ID,"file-upload").send_keys("selenium-snapshot.jpg")
driver.find_element(By.ID,"file-submit").submit()
if(driver.page_source.find("File Uploaded!")):
print("file upload success")
else:
print("file upload not successful")
driver.quit()
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace SeleniumDocumentation.SeleniumPRs
{
class FileUploadExample
{
static void Main(String[] args)
{
IWebDriver driver = new ChromeDriver();
try
{
// Navigate to Url
driver.Navigate().GoToUrl("https://the-internet.herokuapp.com/upload");
driver.FindElement(By.Id("file-upload")).SendKeys("selenium-snapshot.jpg");
driver.FindElement(By.Id("file-submit")).Submit();
if (driver.PageSource.Contains("File Uploaded!"))
{
Console.WriteLine("file uploaded");
}
else
{
Console.WriteLine("file not uploaded");
}
driver.Quit();
}
}
}
// Help us by sending a code sample for file upload
// Help us by sending a code sample for file upload
// Help us by sending a code sample for file upload
So the above example code helps to understand how we can upload a file using Selenium.
3 - ThreadGuard
This class is only available in the Java Binding
ThreadGuard checks that a driver is called only from the same thread that created it. Threading issues especially when running tests in Parallel may have mysterious and hard to diagnose errors. Using this wrapper prevents this category of errors and will raise an exception when it happens.
The following example simulate a clash of threads:
public class DriverClash {
//thread main (id 1) created this driver
private WebDriver protectedDriver = ThreadGuard.protect(new ChromeDriver());
static {
System.setProperty("webdriver.chrome.driver", "<Set path to your Chromedriver>");
}
//Thread-1 (id 24) is calling the same driver causing the clash to happen
Runnable r1 = () -> {protectedDriver.get("https://selenium.dev");};
Thread thr1 = new Thread(r1);
void runThreads(){
thr1.start();
}
public static void main(String[] args) {
new DriverClash().runThreads();
}
}
The result shown below:
Exception in thread "Thread-1" org.openqa.selenium.WebDriverException:
Thread safety error; this instance of WebDriver was constructed
on thread main (id 1)and is being accessed by thread Thread-1 (id 24)
This is not permitted and *will* cause undefined behaviour
As seen in the example:
protectedDriver
Will be created in Main thread- We use Java
Runnable
to spin up a new process and a newThread
to run the process - Both
Thread
will clash because the Main Thread does not haveprotectedDriver
in it’s memory. ThreadGuard.protect
will throw an exception.
Note:
This does not replace the need for using ThreadLocal
to manage drivers when running parallel.