The core libraries of Selenium try to be low level and non-opinionated. The Support classes in each language provide opinionated wrappers for common interactions that may be used to simplify some behaviors.
This is the multi-page printable view of this section. Click here to print.
Support Features
1 - Trabalhando com cores
Ocasionalmente, você desejará validar a cor de algo como parte de seus testes; o problema é que as definições de cores na web não são constantes. Não seria bom se houvesse uma maneira fácil de comparar uma representação HEX de uma cor com uma representação RGB de uma cor, ou uma representação RGBA de uma cor com uma representação HSLA de uma cor?
Não se preocupe. Existe uma solução: a classe Color!
Em primeiro lugar, você precisará importar a classe:
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
Agora você pode começar a criar objetos coloridos. Cada objeto de cor precisará ser criado a partir de uma representação de string de sua cor. As representações de cores com suporte são:
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)')
// Essa funcionalidade não está implementada - Nos ajude enviando um PR implementando essa funcionalidade
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)")
A classe Color também suporta todas as definições de cores básicas especificadas em 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')
// Essa funcionalidade não está implementada - Nos ajude enviando um PR implementando essa funcionalidade
private val BLACK = Color.fromString("black")
private val CHOCOLATE = Color.fromString("chocolate")
private val HOTPINK = Color.fromString("hotpink")
Às vezes, os navegadores retornam um valor de cor “transparent” se nenhuma cor foi definida em um elemento. A classe Color também oferece suporte para isso:
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')
// Essa funcionalidade não está implementada - Nos ajude enviando um PR implementando essa funcionalidade
private val TRANSPARENT = Color.fromString("transparent")
Agora você pode consultar com segurança um elemento para obter sua cor / cor de fundo sabendo que qualquer resposta será analisada corretamente e convertido em um objeto Color válido:
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'))
// Essa funcionalidade não está implementada - Nos ajude enviando um PR implementando essa funcionalidade
val loginButtonColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("color"))
val loginButtonBackgroundColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("background-color"))
Você pode então comparar diretamente os objetos coloridos:
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)
// Essa funcionalidade não está implementada - Nos ajude enviando um PR implementando essa funcionalidade
assert(loginButtonBackgroundColour.equals(HOTPINK))
Ou você pode converter a cor em um dos seguintes formatos e realizar uma validação estática:
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)')
// Essa funcionalidade não está implementada - Nos ajude enviando um PR implementando essa funcionalidade
assert(loginButtonBackgroundColour.asHex().equals("#ff69b4"))
assert(loginButtonBackgroundColour.asRgba().equals("rgba(255, 105, 180, 1)"))
assert(loginButtonBackgroundColour.asRgb().equals("rgb(255, 105, 180)"))
As cores não são mais um problema.
2 - ThreadGuard
Esta classe está disponível apenas no Java Binding
ThreadGuard verifica se um driver é chamado apenas da mesma thread que o criou. Problemas de threading, especialmente durante a execução de testes em paralelo, podem ter erros misteriosos e difíceis de diagnosticar. Usar este wrapper evita esta categoria de erros e gerará uma exceção quando isso acontecer.
O exemplo a seguir simula um conflito de threads:
public class DriverClash {
//thread main (id 1) criou este driver
private WebDriver protectedDriver = ThreadGuard.protect(new ChromeDriver());
static {
System.setProperty("webdriver.chrome.driver", "<Set path to your Chromedriver>");
}
//Thread-1 (id 24) está chamando o mesmo driver causando o conflito
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();
}
}
O resultado mostrado abaixo:
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
Conforme visto no exemplo:
protectedDriver
será criado no tópico principal- Usamos Java
Runnable
para ativar um novo processo e uma novaThread
para executar o processo - Ambas as
Thread
s entrarão em conflito porque a thread principal não temprotectedDriver
em sua memória. ThreadGuard.protect
lançará uma exceção.
Nota:
Isso não substitui a necessidade de usar ThreadLocal
para gerenciar drivers durante a execução em paralelo.
3 - Trabalhando com elementos select
The Select object will now give you a series of commands
that allow you to interact with a <select>
element.
If you are using Java or .NET make sure that you’ve properly required the support package in your code. See the full code from GitHub in any of the examples below.
Note that this class only works for HTML elements select
and option
.
It is possible to design drop-downs with JavaScript overlays using div
or li
,
and this class will not work for those.
Types
Select methods may behave differently depending on which type of <select>
element is being worked with.
Single select
This is the standard drop-down object where one and only one option may be selected.
<select name="selectomatic">
<option selected="selected" id="non_multi_option" value="one">One</option>
<option value="two">Two</option>
<option value="four">Four</option>
<option value="still learning how to count, apparently">Still learning how to count, apparently</option>
</select>
Multiple select
This select list allows selecting and deselecting more than one option at a time.
This only applies to <select>
elements with the multiple
attribute.
<select name="multi" id="multi" multiple="multiple">
<option selected="selected" value="eggs">Eggs</option>
<option value="ham">Ham</option>
<option selected="selected" value="sausages">Sausages</option>
<option value="onion gravy">Onion gravy</option>
</select>
Create class
First locate a <select>
element, then use it to initialize a Select
object.
Note that as of Selenium 4.5, you can’t create a Select
object if the <select>
element is disabled.
WebElement selectElement = driver.findElement(By.name("selectomatic"));
Select select = new Select(selectElement);
select_element = driver.find_element(By.NAME, 'selectomatic')
select = Select(select_element)
var selectElement = driver.FindElement(By.Name("selectomatic"));
var select = new SelectElement(selectElement);
select_element = driver.find_element(name: 'selectomatic')
select = Selenium::WebDriver::Support::Select.new(select_element)
const selectElement = await driver.findElement(By.name('selectomatic'))
const select = new Select(selectElement)
val selectElement = driver.findElement(By.name("selectomatic"))
val select = Select(selectElement)
List options
There are two lists that can be obtained:
All options
Get a list of all options in the <select>
element:
List<WebElement> optionList = select.getOptions();
option_list = select.options
IList<IWebElement> optionList = select.Options;
option_list = select.options
const optionList = await select.getOptions()
val optionList = select.getOptions()
Selected options
Get a list of selected options in the <select>
element. For a standard select list
this will only be a list with one element, for a multiple select list it can contain
zero or many elements.
List<WebElement> selectedOptionList = select.getAllSelectedOptions();
selected_option_list = select.all_selected_options
IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
selected_option_list = select.selected_options
const selectedOptionList = await select.getAllSelectedOptions()
val selectedOptionList = select.getAllSelectedOptions()
Select option
The Select class provides three ways to select an option. Note that for multiple select type Select lists, you can repeat these methods for each element you want to select.
Text
Select the option based on its visible text
select.selectByVisibleText("Four");
select.select_by_visible_text('Four')
select.SelectByText("Four");
select.select_by(:text,'Four')
await select.selectByVisibleText('Four')
select.selectByVisibleText("Four")
Value
Select the option based on its value attribute
select.selectByValue("two");
select.select_by_value('two')
select.SelectByValue("two");
select.select_by(:value,'two')
await select.selectByValue('two')
select.selectByValue("two")
Index
Select the option based on its position in the list
select.selectByIndex(3);
select.select_by_index(3)
select.SelectByIndex(3);
select.select_by(:index,3)
await select.selectByIndex(3)
select.selectByIndex(3)
Disabled options
Options with a disabled
attribute may not be selected.
<select name="single_disabled">
<option id="sinlge_disabled_1" value="enabled">Enabled</option>
<option id="sinlge_disabled_2" value="disabled" disabled="disabled">Disabled</option>
</select>
Assertions.assertThrows(UnsupportedOperationException.class, () -> {
select.selectByValue("disabled");
});
with pytest.raises(NotImplementedError):
select.select_by_value('disabled')
Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
expect {
select.select_by(:value, 'disabled')
}.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
await assert.rejects(async () => {
await select.selectByValue("disabled")
}, {
name: 'UnsupportedOperationError',
Assertions.assertThrows(UnsupportedOperationException::class.java) {
select.selectByValue("disabled")
}
De-select option
Only multiple select type select lists can have options de-selected. You can repeat these methods for each element you want to select.
select.deselectByValue("eggs");
select.deselect_by_value('eggs')
select.DeselectByValue("eggs");
select.deselect_by(:value, 'eggs')
await select.deselectByValue('eggs')
select.deselectByValue("eggs")