Si quieren aprender de selectores,en especial de XPATH les recomiendo el curso de Facundo es muy bueno,directo y claro,van a dominar el uso de selectores. ver curso
En ocasiones algunos sitios pueden tener bloqueos regionales o no estar disponibles por la alta cantidad de solicitudes que llegan a tener. Si el sitio de práctica no abre, puedes intentar ingresando a OneStepCheckout Responsive Demo.
Si quieren aprender de selectores,en especial de XPATH les recomiendo el curso de Facundo es muy bueno,directo y claro,van a dominar el uso de selectores. ver curso
Código más actualizado y con los nuevos estándares.
Recomiendo leer para localizar elementos Añadi una 's' en el enlace al sitio en driver.get('url') asegurate de eliminarla, fue necesario para hacer este comentario en Platzi .
import unittest
from pyunitreport import HTMLTestRunner
from selenium import webdriver
# By nos permite el uso de 2 métodos privados find_elements(selector, 'value') y find_element(By.ID, "search")
from selenium.webdriver.common.by import By
# Service nos ayuda a declarar el executable_path() de nuestro webdriver.
# Yo utilizo chrome pero deberias poder hacerlo con otro navegador.
from selenium.webdriver.chrome.service import Service
class Search(unittest.TestCase):
def setUp(self):
# creamos una variable s con una funcion Service('') que contiene la ruta del webdriver.
s=Service('./chromedriver')
# establecemos la referencia del driver
self.driver = webdriver.Chrome(service=s)
driver = self.driver
driver.get("https://demo.onestepcheckout.com/")
driver.maximize_window()
driver.implicitly_wait(5)
def test_search_text_field(self):
dsearch_field = self.driver.find_element(By.ID, "search")
def test_search_by_name(self):
search_field = self.driver.find_element(By.NAME, "q")
def test_search_by_class(self):
search_field = self.driver.find_element(By.CLASS_NAME, "input-text")
def test_search_button(self):
search_button = self.driver.find_element(By.CLASS_NAME, "search-button")
def test_search_banner_img(self):
banner_list = self.driver.find_element(By.CLASS_NAME, "promos")
banner = banner_list.find_elements(By.TAG_NAME, "img")
self.assertEqual(3, len(banner))
def test_vip_promo(self):
vip_promo = self.driver.find_element(By.XPATH,"//*[@id='top']/body/div/div[2]/div[2]/div/div/div[2]/div/ul/li[4]/a/img")
def test_icon_cart(self):
icon_cart = self.driver.find_element(By.CSS_SELECTOR,"div.header-minicart span.icon")
def tearDown(self):
self.driver.quit()
if __name__ == '__main__':
unittest.main(verbosity = 2)
Usualmente las personas que hemos trabajado con selenium seguimos una prioridad para encontrar elementos.
En mi caso yo uso la siguiente.
Si bien con selenium debemos correr el script de principio a fin y no podemos partir de un punto intermedio, pytest nos permite ejecutar tests específicos, solo tienes que poner en la consola:
pytest search_tests.py::HomePageTests::test_count_of_promo_banner_images
Donde cada "::" nos permite bajar un nivel
Archivo::Clase::Test
Version de selenium 4.3.0: se cambiaron los buscadores por las formas de buscar, donde ahora find_elements o find_element se incluye solo y dentro de los paretesis se incluyo el selector o el buscador especifico ejem antes se escribía de esta forma "self.driver.find_element_by_class_name( "button")" ahora es "self.driver.find_element("class name", "button")" de igual forma para todos los delas buscadores
import unittest
from selenium import webdriver
class SearchTests(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.driver = webdriver.Chrome(executable_path = "C:\webdriver\chromedriver.exe")
driver = cls.driver
driver.get('http://demo-store.seleniumacademy.com')
driver.maximize_window()
driver.implicitly_wait(5)
def test_search_test_field(self):
search_field = self.driver.find_element("id", "search")
def test_search_test_field_by_name(self):
search_field = self.driver.find_element("name", "q")
def test_search_test_field_class_name(self):
search_field = self.driver.find_element("class name", "input-text")
def test_search_button_enable(self):
button = self.driver.find_element("class name", "button")
def test_count_of_promo_banner_images(self):
banner_list = self.driver.find_element("class name", "promos")
banners = banner_list.find_elements("tag name", 'img')
self.assertEqual(3, len(banners))
def test_vip_promo(self):
vip_promo = self.driver.find_elements('xpath', '//*[@id="top"]/body/div/div[2]/div[2]/div/div/div[2]/div[1]/ul/li[4]/a/img')
def test_shopping_cart(self):
shopping_cart_icon = self.driver.find_element("css selector", "div.header-minicart span.icon")
def test_search_tee(self):
driver = self.driver
search_field = driver.find_element("name", "q")
search_field.clear()
search_field.send_keys("tee")
search_field.submit()
def test_search_salt_shaker(self):
driver = self.driver
search_field = driver.find_element("name", "q")
search_field.clear()
search_field.send_keys("salt shaker")
search_field.submit()
products = driver.find_elements("xpath", '/html/body/div/div[2]/div[2]/div/div[2]/div[2]/div[3]/ul/li/div/h2/a')
self.assertEqual(1, len(products))
@classmethod
def tearDownClass(cls):
cls.driver.quit()
if __name__ == '__main__':
unittest.main(verbosity = 2)
Si ustedes le ponen un docstring a los tests así: 
El informe de los tests en la consola usará ese docstring en lugar del nombre del método del test:

Considerar que es 'elementS' con S, ya que lo puse en singular y me arrojaba el siguiente error:
TypeError: object of type 'WebElement' has no len()
Saludos.
Para quienes no les funciona el enlace esta este Madison Island
Hola
Les dejo el código por acá:
import unittest from pyunitreport import HTMLTestRunner from selenium import webdriver
class EcomerceHomePage(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome(executable_path= r'C:\Aprendiendo\Selenium\chromedriver.exe')
driver = self.driver
driver.get("http://demo-store.seleniumacademy.com")
driver.maximize_window()
driver.implicitly_wait(10)
def test_search_text_field(self):
search_field = self.driver.find_element_by_id("search")
def test_search_text_field_by_name(self):
search_field = self.driver.find_element_by_name("q")
def test_search_text_field_by_class(self):
search_field = self.driver.find_element_by_class_name("input-text")
def test_search_button_enabled(self):
button = self.driver.find_element_by_class_name("input-text")
def test_count_of_promo_bar(self):
banner_list = self.driver.find_element_by_class_name("promos")
banners = banner_list.find_elements_by_tag_name('img')
self.assertEqual(3,len(banners))
def test_vip_promo(self):
vip_promo = self.driver.find_element_by_xpath('//*[@id="top"]/body/div/div[2]/div[2]/div/div/div[2]/div[1]/ul/li[4]/a/img')
def test_shopping_cart(self):
shopping_cart_icon = self.driver.find_element_by_css_selector("div.header-minicart span.icon")
def tearDown(self):
self.driver.quit()
if name == "main": unittest.main(verbosity = 2, testRunner = HTMLTestRunner(output= 'reportes',report_name= 'Ecomerce_report'))
Quiero generar un aporte con respecto a esta clase, probablemente por el cambio de versiones tanto de python( mi versión 3.11) como de selenium, nuevamente no me funciona lo indicado en el video, investigando encontré que se debe importar la clase "By" de selenium(Linea 6), a continuación se muestra como me funciono:
