This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Additional Features

Set of packages and functionalities to simplify automation with Selenium.

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 nova Thread para executar o processo
  • Ambas as Threads entrarão em conflito porque a thread principal não tem protectedDriver 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.