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
Conocer el ecosistema de Selenium
Por qué aprender Selenium y qué verás
Historia de Selenium
Otras herramientas de testing y automatización
Preparar entorno de trabajo
Configurar entorno de trabajo
Compatibilidad con Python 3.9 y aprendiendo a utilizar múltiples versiones
¡Hola, mundo!
Utilizar comandos básicos
Encontrar elementos con find_element
Preparar assertions y test suites
Entender las clases WebDriver y WebElement
Interactuar con elementos
Manejar form, textbox, checkbox y radio button
Manejar dropdown y listas
Manejar alert y pop-up
Automatizar navegación
Sincronizar pruebas
Demora implícita y explícita
Condicionales esperadas
Retos
Agregar y eliminar elementos
Elementos dinámicos
Controles dinámicos
Typos
Ordenar tablas
Metodologías de Trabajo
Data Driven Testing (DDT)
Page Object Model (POM)
Cierre del curso
Realizar una prueba técnica
Conclusiones
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Héctor Vega
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.
Aportes 89
Preguntas 37
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
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:
Les comparto como queda el código con los métodos actualizados.
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’))
No seria mala idea actualizar este curso, lleva mas de dos años
En las nuevas versiones de selenium los selectores se usan de la siguiente forma :
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_name(self):
search_field = self.driver.find_element(By.CLASS_NAME,"input-text")
En 2022 muchos de estos comandos ya están en desuso ahora se usa el metodo find_element enviando como parametro la carcaterisica por la que se va a hacer la busqueda aca se pueden ver los ejemplos completos
Actualmente el find_element_by_*
esta deprecado, por lo que debemos hacer algunas actualizaciones:
from selenium.webdriver.common.by import By
def test_search(self):
search = self.driver.find_element_by_*("x")
# Lo reemplazamos por
def test_search(self):
search = self.driver.find_element(By.CLASS_NAME, "x")
Selectores
Selectores
import unittest
from pyunitreport import HTMLTestRunner
from selenium import webdriver
class HomePageTest(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome(executable_path=r"./chromedriver.exe")
driver = self.driver
driver.get("http://demo-store.seleniumacademy.com/")
driver.maximize_window()
driver.implicitly_wait(2)
def test_search_text_fiels(self): #Busca por ID
search_field = self.driver.find_element_by_id("search")
def test_search_text_field_by_name(self): #Busca por name
search_field = self.driver.find_element_by_name("q")
def test_search_text_field_class_name(self): #Busca por class name
search_field = self.driver.find_element_by_class_name("input-text")
def test_search_button_enabled(self): #Busca por class name
buttom = self.driver.find_element_by_class_name("button")
def test_count_of_promo_banner_images(self):
banner_list = self.driver.find_element_by_class_name("promos")
banners = banner_list.find_elements_by_tag_name('img') # Crea variable con los elementos del objeto IMG por tag
self.assertEqual(3, len(banners)) # Verifica validacion conteo de los elementos del objeto
def test_vip_promo(self): #Busca por XPath - Tocar dale copiar y decirle para xpath en el sitio
vip_promo = self.driver.find_element_by_xpath('/html/body/div/div[2]/div[2]/div/div/div[2]/div[1]/ul/li[2]/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): #Cerar la prueba - cerrar el navegador
self.driver.quit()
if __name__ == "__main__":
unittest.main(verbosity=2)
Si no les sale el find_elemen_by_lo que sea y solo te sale
driver.find_element
Lo único que tienes que hacer es importar una nueva librería:
from selenium(.)webdriver(.)common(.)by import By
solo quitar los parentesis
Y la sintaxis aquí seria:
find_element(By.atributo, ‘nombre del atributo’)
Por ejemplo:
find_element(By . ID, ‘header-search’)
Y listo, toda la clase funciona
A mi me sale este error 😦
Al parecer esta sintaxis ya no es valida, seria estupendo actualizar este grandioso curso. La documentación para Python es Selenium doc
Espero les sirve.
<code>
ACTUALIZACION:
1- debemos importar:
from selenium.webdriver.common.by import By
2- debemos escribir correctamente le siguiente:
def test_search_text_field(self):
search_field= self.driver
search_field.find_element(By.ID, "search")
*Me funcionó asi, espero les sirva y se ahorren tiempo.
igual si buscan en la documentacion de selenium les sale (por si vuelven a actualizar)
El link de la pagina estaba caído cuando vi el video, yo utilicé esta otra pagina por si a alguien le sirve.
Pd. Yo utilicé Microsoft Edge Chromium, si usan google chrome solo cambien la parte del principio del código (setUp).
import unittest
from pyunitreport import HTMLTestRunner
from selenium import webdriver
class HelloWorld(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Edge(executable_path = './edgedriver/msedgedriver.exe')
self.driver.get("http://automationpractice.com/index.php")
self.driver.maximize_window()
self.driver.implicitly_wait(5)
def test_search_text_field(self):
search_field = self.driver.find_element_by_id("search_query_top")
def test_search_text_field_by_name(self):
search_field = self.driver.find_element_by_name("search_query")
def test_search_text_field_by_class_name(self):
search_field = self.driver.find_element_by_class_name("search_query")
def test_search_button_enabled(self):
button = self.driver.find_element_by_class_name("btn")
def test_count_of_promo_banner_images(self):
banner_list = self.driver.find_element_by_class_name("htmlcontent-home")
banners = banner_list.find_elements_by_tag_name('img')
self.assertEqual(2, len(banners))
def test_promo(self):
promo = self.driver.find_element_by_xpath('//*[@id="homeslider"]/li[4]/a/img')
def test_shopping_cart(self):
shopping_cart_icon = self.driver.find_element_by_css_selector("div.shopping_cart a")
def tearDown(self):
self.driver.quit()
if __name__ == '__main__':
unittest.main(verbosity = 2, testRunner = HTMLTestRunner(output = 'reportes', report_name = 'search-test-report'))
IMPORTANTE: Selenium a partir de la versión (4.3.0) eliminó find_element_by_ y find_elements_by_ por lo cual ya no se puede usar.
Solución, cambiar por:
driver.find_element(By.XPATH, " ")
driver.find_elements(By.XPATH, " ")
driver.find_element(By.CLASS_NAME, " ")
driver.find_elements(By.CLASS_NAME, " ")
https://github.com/SeleniumHQ/selenium/blob/a4995e2c096239b42c373f26498a6c9bb4f2b3e7/py/CHANGES
En Selenium, podemos usar los selectores de las páginas web para llegar a los elementos, como son:
Podemos practicar en Madison Island
Instrucciones usadas en esta clase:
self.driver.find_element_by_id
-> Encontrar elemento por su IDself.driver.find_element_by_name
-> Encontrar elemento por su nameself.driver.find_element_by_class_name
-> Encontrar elemento por nombre de clase CSSfind_elements_by_tag_name
-> Encontrar elementos por sus etiquetas HTMLself.driver.find_element_by_xpath
-> Encontrar elemento por su XPATHself.driver.find_element_by_css_selector
-> Encontrar elemento por su selector CSSCódigo de la clase (en WSL):
search_test.py
import unittest
from pyunitreport import HTMLTestRunner
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
class HelloWorld(unittest.TestCase):
@classmethod
def setUpClass(cls):
options = Options()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
cls.driver = webdriver.Chrome(executable_path = '/usr/bin/chromedriver' , options=options)
driver = cls.driver
driver.get('ENLACE_DE_LA_WEB_QUE_PLATZI_NO_ME_DEJA_ESCRIBIR_AQUI')
#driver.maximize_window()
#driver.implicitly_wait(15) # segundos
def test_search_text_fild(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_class_name(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("button")
def test_count_of_promo_banner_images(self):
banner_list = self.driver.find_element_by_class_name("promos") #Buscamos la clase "promos"
banners = banner_list.find_elements_by_tag_name("img") #Buscamos las etiquetas img dentro de promos
self.assertEqual(3, len(banners)) #Hacemos una assertion para ver si efectivamente es la cantidad de imágenes que esperamos
#! NO son 3 imágenes, son 4, pero recordemos que se cuenta: [0,1,2,3]
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")
@classmethod
def tearDownClass(cls):
cls.driver.quit()
if __name__ == '__main__':
unittest.main(verbosity = 2)
Comparto la sección localizar elementos de la documentación de Selenium para Python (no oficial)
https://selenium-python.readthedocs.io/locating-elements.html
Version 4.8.2 de Selenium: se agregaron constantes para tener un código más limpio, a continuación un ejemplo de cómo queda:
import unittest
from selenium import webdriver
from selenium.webdriver.common.by import By
class HomePageTests(unittest.TestCase):
def setUp(self) -> None:
self.driver = webdriver.Chrome(executable_path='./chromedriver')
driver = self.driver
driver.get("https://demo-store.seleniumacademy.com/")
driver.maximize_window()
driver.implicitly_wait(15)
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, "button")
def test_count_of_promo_banner_images(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):
xpath_value = '//*[@id="top"]/body/div/div[2]/div[2]/div/div/div[2]/div[1]/ul/li[4]/a/img'
vip_promo = self.driver.find_element(By.XPATH, xpath_value)
def test_shopping_cart(self):
shopping_cart_icon = self.driver.find_element(By.CSS_SELECTOR, "div.header-minicart span.icon")
def tearDown(self) -> None:
self.driver.quit()
if __name__ == "__main__":
unittest.main(verbosity=2)
A pesar de que no está actualizado el contenido con la ultima version, he podido aclarar varias cosas que no tenía claras cuando había usado Selenium tiempo atrás y no es solo gracias a este curso, muchos otros que he tomado estos meses me han permitido fortalecer la bases.
P. D: el codigo esta corriendo en ubuntu 22.04 y con chrome
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from pyunitreport import HTMLTestRunner
from selenium import webdriver
import unittest
class FindElements(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome(
service=Service(r"./driver/chromedriver"))
driver = self.driver
driver.get("https://demo-store.seleniumacademy.com/")
driver.maximize_window()
driver.implicitly_wait(10)
def testSearchFieldId(self):
search_field = self.driver.find_element(By.ID, "search")
def testSearchFieldName(self):
search_field = self.driver.find_element(By.NAME, "q")
def testSearchFieldClass(self):
search_field = self.driver.find_element(
By.CLASS_NAME, "input-text")
def testSearchButtonClass(self):
search_field = self.driver.find_element(By.CLASS_NAME, "button")
def testListImages(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 testImage(self):
xpath = '//*[@id="top"]\
/body/div/div[2]/div[2]/div/div/div[2]/ul/li[1]/a/img'
banner = self.driver.find_element(By.XPATH, xpath)
def testCart(self):
shopping_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, testRunner=HTMLTestRunner(
output="reports", report_name="findElements_report"))
hola aquí dejo una versión actualizada del código
import unittest
from pyunitreport import HTMLTestRunner
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
class FindElements(unittest.TestCase):
#El SetUp es una función de preparación para la prueba, algo así como alistar las precondiciones
def setUp(self):
service = Service(executable_path= r'C:\Users\Melissa\OneDrive\Documentos\Selenium\chromedriver_win32\chromedriver.exe')
self.driver = webdriver.Chrome(service=service)
self.driver.get("https://www.youtube.com")
self.driver.maximize_window()
#Si se necesita un tiempo de espera se usa la línea de abajo
self.driver.implicitly_wait(10)
#Acceder a un sitio web
#Hay que poner test_ para que el sistema lo reconozca como caso de prueba
def test_SearchElementID(self):
searchField = search_field=self.driver.find_element(By.ID, 'search')
def test_SearchElementName(self):
searchField=search_field=self.driver.find_element(By.NAME, 'search_query')
def test_SearchElementClass(self):
search_field=self.driver.find_element(By.CLASS_NAME, 'gstl_50 sbdd_c')
#En caso de listas de elementos
def test_SearchElementClass(self):
listaElementos = self.driver.find_element(By.NAME, 'nombre')
elementos = self.driver.find_element(By.TAG_NAME, 'nombreElemento')
#Para verificar la cantidad de elementos usamos assertion
#Assertion es un validación que se hace en el codigo para verificar que se cumple o no una condición
self.assertEqual(3, len(elementos))
def tearDown(self) -> None:
self.driver.quit()
if __name__ == "__main__":
unittest.main(verbosity = 2, testRunner = HTMLTestRunner(output = 'reportes', report_name = 'find-elements-report'))
El uso de find_element_by_SELECTOR
esta deprecado.
Ahora lo que se debe hacer es importar from selenium.webdriver.common.by import By
y encontrar elementos de la siguiente forma find_elements(By.CLASS_NAME, 'foo')
from selenium.webdriver.common.by import By
def test_search(self):
search_field = self.driver.find_element(By.ID, 'search')
def test_search_test_by_name(self):
search_field = self.driver.find_element(By.NAME, 'q')
def test_search_test_class_name(self):
search_field = self.driver.find_element(By.CLASS_NAME, 'input-text')
def test_search_button_enabled(self):
search_field = self.driver.find_element(By.CLASS_NAME, 'button')
def test_count_of_promo_banner_images(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))
Actualización: search_field = self.driver.find_element(“id”, “search”)
La librería fue actualizada y actualmente ya no se usan las funciones que vienen dentro de la instancia driver, para esto se debe importar desde Selenium el módulo By y hacer solo uso de la función find_element de driver, por ejemplo:
from selenium.webdriver.common.by import By
#----
def test_search_text_field(self):
search_field = self.driver.find_element(By.ID, "search")
#---
Enlace a la documentación: Selenium Documentación
actualmente el find element esta deprecated, se debe usar asi:
from selenium.webdriver.common.by import By
self.driver.find_element(by=By.NAME, value="username")
Este curso está genial
No me abre el link de la demo-store. ¿Tal vez selenium academy se dio cuenta que mucho lo usaban sin pagar la membresía?
Que gran curso. La verdad es que parece magia haciendo que se ejecute todo a través de código. Le voy a seguir dando de “Hacha y Tiza”.
Hola Profe Hector!, tengo una duda: Por qué solo se ejecuta exitosamente el script de Test cuando adiciono los decoradoradores, en el video a ti te funciona bien sin ellos también. Me gustaría entender esa situación! 😃. Gracias! por acá dejo mi código
Para que funcione el enlace deben poner:
driver.get(“http://demo.onestepcheckout.com/”)
Muy interesante el curso, pero me pueden ayudar en entender que usos prácticos podría tener esta herramienta?. Me cuesta mucho imaginarme casos reales donde aplicarlo. Gracias
alguien ha intentado hacer automatizaciones en sitios donde se require subir archivos desde una maquina despelgando el menú de selección de archivos de windows o de mac?, hay forma de manejar eso en selenium?
Si instalaron selenium 4.3.0 se van a encontrar con el siguiente error:
AttributeError: 'WebDriver' object has no attribute 'find_element_by_name'
esto se debe a que para esta version fue removido este método
https://github.com/SeleniumHQ/selenium/blob/a4995e2c096239b42c373f26498a6c9bb4f2b3e7/py/CHANGES
ahora hay que utilizar algo como esto:
driver.find_element("name", "q")
Comparto mi código probado en Linux (ubuntu)
import unittest
from pyunitreport import HTMLTestRunner
from selenium import webdriver
from selenium.webdriver.common.by import By
class HomePageTests(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome(executable_path='/usr/bin/chromedriver')
driver = self.driver
driver.get('http://demo-store.seleniumacademy.com/')
driver.maximize_window()
driver.implicitly_wait(5)
def test_search_text_field(self):
search_field = self.driver.find_element(By.ID, "search")
def test_seach_by_name(self):
search_field = self.driver.find_elements(By.CLASS_NAME, "q")
def test_search_by_class_name(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_images(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 text_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_search_csc(self):
shopping_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, testRunner = HTMLTestRunner(output='reportes', report_name =' search_test-report'))
A fecha 20/12/2022 el siguiente código para firefox, W11 y con el ambiente virtual creado.
import unittest
from pyunitreport import HTMLTestRunner
from selenium import webdriver
from selenium.webdriver.common.by import By
class HomePageTest(unittest.TestCase):
@classmethod
def setUpClass(self):
self.driver = webdriver.Firefox(executable_path = r'.\geckodriver.exe')
driver = self.driver
driver.get('[ENLACE]/')
driver.maximize_window()
driver.implicitly_wait(15)
def test_search_text_field_by_id(self):
search_field = self.driver.find_element(By.ID, "search")
def test_count_promo_banner_images(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_search_private_sales_button_by_xpath(self):
XPATH = "/html/body/div/div[2]/div[2]/div/div/div[2]/ul/li[2]/a/img"
private_sales_button = self.driver.find_element(By.XPATH, XPATH)
def test_search_shopping_cart_icon_by_css_selector(self):
shopping_cart_icon = self.driver.find_element(By.CSS_SELECTOR, "div.header-minicart span.icon")
@classmethod
def tearDownClass(cls):
cls.driver.quit()
if __name__ == "__main__":
unittest.main(verbosity = 2, testRunner = HTMLTestRunner(output = 'reportes', report_name = 'HomePageTestReport') )
Hola a mi no me funciono la instrucción de fin_alement_by_id entonces investigando encontré otra forma find_element(“id”,“elemento-a-buscar”) si queremos buscar otro tipo de selecctor cambiamos id por css, xpath etc.
def test_search_text_field(self):
search_field = self.driver.find_element("id","fila-seccion-paginas-principales")
print ("hola",search_field)
Selector XPATH, nos permite buscar algun elemento cuando no hay algo lo suficientemente explicito como una classe, id o name. No deberia ser XPATH una de las primeras opciones a utilizar en busqueda de algun elemento
import time
time.sleep(15)
# en ves de utilizar driver.implicity_wait( ) podemos utilizar time.sleep()
Si al igual que yo están usando python 3.9.13 y selenium 4.4.3 quizá les sea interesaqnte este código con los métodos actualizados para la clase Webdriver.
import unittest
from selenium import webdriver
from pyunitreport import HTMLTestRunner
from selenium.webdriver.common.by import By
class HomePageTests(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.driver = webdriver.Chrome(executable_path = 'chromedriver.exe')
cls.driver.get('https://demo-store.seleniumacademy.com/')
cls.driver.maximize_window()
cls.driver.implicitly_wait(15)
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_classname(self):
search_field = self.driver.find_element(By.CLASS_NAME, 'input-text')
# In order to find the seach button we'll need to inspect code again.
def test_search_button(self):
button_search = self.driver.find_element(By.CLASS_NAME, 'button')
# For banner images
def test_banner_images(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_shopping_cart(self):
shopping_cart_icon = self.driver.find_element(By.CSS_SELECTOR, 'div.header-minicart span.icon')
def test_vip_promo(self):
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')
@classmethod
def tearDownClass(cls):
cls.driver.quit()
if __name__ == '__main__':
unittest.main(verbosity = 2,
testRunner = HTMLTestRunner(output = 'reportes', report_name = 'search-report'))
Luego revisan el reporte.
Para quienes tiene el errror de :
.find_element_by_tagname () <- deprecated
tienen que agregar importar:
from selenium.webdriver.common.by import By
y en el codigo usar:
banners = banner_list.find_elements(By.TAG_NAME, value="img")
Codigo de la clase:
import unittest
from selenium import webdriver
from selenium.webdriver.common.by import By
class SearchTests(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome(executable_path = r'.\chromedriver.exe')
driver = self.driver
driver.get('http://demo-store.seleniumacademy.com/')
driver.maximize_window()
driver.implicitly_wait(15)
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_class_name(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("button")
def testo_count_of_promo_banner_images(self):
banner_list = self.driver.find_element_by_class_name("promos")
banners = banner_list.find_elements(By.TAG_NAME, value="img") # ojo para elementos usar find_elements
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[2]/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) # verbosity 2 nos da detalles de lo que esta pasando
| Old API | New API |
| :----------------------------- | :------------------------------ |
| find_element_by_id(‘id’) | find_element(By.ID, ‘id’) |
| find_element_by_name(‘name’) | find_element(By.NAME, ‘name’) |
| find_element_by_xpath(‘xpath’) | find_element(By.XPATH, ‘xpath’) |
también podríamos utilizar algo como esto para la vecino 4.3.0
from selenium.webdriver.common.by import By
driver.find_element(By.XPATH, " ")
driver.find_elements(By.XPATH, " ")
driver.find_element(By.CLASS_NAME, " ")
driver.find_elements(By.CLASS_NAME, " ")
Nose porque recordaba a selenium super anticuado… supongo porque mi 1er contacto fue con JAVA.
por que me aparecen las variable así?
Les comparto el código actualizado
Al menos lo probé y me funcióno correcto, pasando las pruebas
Este es el del hello:wold.py paa que abra as dos páginas en la misma ventana
import unittest
from pyunitreport import HTMLTestRunner
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
class HelloWorld(unittest.TestCase):
__service = Service(executable_path=ChromeDriverManager(path="../chromedriver").install())
__driver = webdriver.Chrome(service = __service)
@classmethod
def setUpClass(self):
self.__driver.implicitly_wait(10)
def test_hello_world(self):
self.__driver.get("https://www.platzi.com")
def test_visit_wikipedia(self):
self.__driver.get("https://www.wikipedia.org/")
@classmethod
def tearDownClass(self):
self.__driver.quit()
if __name__ == '__main__':
unittest.main(verbosity=2, testRunner=HTMLTestRunner(output='reportes', report_name='hello_world_report'))
Durante la práctica a la fecha de hoy, me encontré con algunos deprecation warnings, así que decidí buscar cual era la configuración correcta al día de hoy… Se los comparto.
Tengo este archivo donde guardo las constantes que estaré usando en todas las prácticas
from os import path
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
CURRENT_PATH = path.dirname(path.abspath(__file__))
DRIVER_PATH = path.join(CURRENT_PATH, 'chromedriver')
BINARY_PATH = '/Applications/Brave Browser.app/Contents/MacOS/Brave Browser'
CHROME_OPTIONS = webdriver.ChromeOptions()
CHROME_OPTIONS.binary_location = BINARY_PATH
SERVICE = Service(DRIVER_PATH)
import unittest
from selenium import webdriver
from selenium.webdriver.common.by import By
from common import SERVICE
from common import CHROME_OPTIONS
class HomePageTestCase(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
cls.driver = webdriver.Chrome(
service=SERVICE,
options=CHROME_OPTIONS,
)
cls.driver.get('URL') # Añadir URL; Platzi no deja poner el comentario porque la ruta no es HTTPS
cls.driver.maximize_window()
cls.driver.implicitly_wait(15)
def test_search_text_field(self):
search_field = self.driver.find_element(by=By.ID, value='search')
def test_search_text_field_by_name(self):
search_field = self.driver.find_element(by=By.NAME, value='q')
def test_search_text_field_by_class_name(self):
search_field = self.driver.find_element(by=By.CLASS_NAME, value='input-text')
def test_search_button_is_enabled(self):
search_button = self.driver.find_element(by=By.CLASS_NAME, value='button')
def test_count_of_promo_banner_images(self):
banner_list = self.driver.find_element(by=By.CLASS_NAME, value='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=By.XPATH, value='//*[@id="top"]/body/div/div[2]/div[2]/div/div/div[2]/div[1]/ul/li[3]/a/img')
def test_shopping_cart(self):
shopping_cart_icon = self.driver.find_element(by=By.CSS_SELECTOR, value='div.header-minicart span.icon')
@classmethod
def tearDownClass(cls) -> None:
cls.driver.quit()
if __name__ == '__main__':
unittest.main(verbosity=2)
Hola a todos. A continuación comparto el codigo que utilice en el ejericicio :
import unittest
from pyunitreport import HTMLTestRunner
from selenium import webdriver
class Selectores(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome(executable_path = r'C:\chromedriver\chromedriver.exe')
driver = self.driver
driver.get("direccion sitio web/")
driver.maximize_window()
driver.implicitly_wait(15)
def test_search_test_field(self):
search_field =self.driver.find_element_by_id("search")
def test_search_text_field(self):
search_field = self.driver.find_element_by_name("q")
def test_search_text_field_class_name(self):
search_field = self.driver.find_element_by_class_name("input-text")
def test_search_button_anabled(self):
button = self.driver.find_element_by_class_name("button")
def test_count_of_promo_banner_images(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)
despues de hacer el curso xpath de facundo, no me parece que sea una mala idea como el profesor la pinta
notitas
Selectores
Codigo de la clase
import unittest
from pyunitreport import HTMLTestRunner
from selenium import webdriver
class HelloWorld(unittest.TestCase):
@classmethod
def setUp(cls):
cls.driver = webdriver.Chrome(executable_path='./chromedriver')
driver = cls.driver
driver.implicitly_wait(10)
driver.get("https![Captura de Pantalla 2021-08-26 a la(s) 6.06.09.png](https://static.platzi.com/media/user_upload/Captura%20de%20Pantalla%202021-08-26%20a%20la%28s%29%206.06.09-f38313fc-d3e7-449e-aa50-8432beb10e9a.jpg)://demo-store.seleniumacademy.com/")
driver.maximize_window()
driver.implicitly_wait(15)
def test_search_text_field(cls):
search_field = cls.driver.find_element_by_id("search")
def test_search_text_field_by_name(cls):
search_field = cls.driver.find_element_by_name("q")
def test_search_text_field_by_class_name(cls):
search_field = cls.driver.find_element_by_class_name("input-text")
def test_search_button_enabled(cls):
button = cls.driver.find_element_by_class_name("button")
def test_count_of_promo_banner_images(cls):
baner_list = cls.driver.find_element_by_class_name("promos")
baners = baner_list.find_elements_by_tag_name("img")
cls.assertEqual(3, len(baners))
def test_vip_promo(cls):
vip_promo = cls.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_shoping_car(cls):
shopping_car = cls.driver.find_element_by_css_selector("div.header-minicart span.icon")
def tearDown(cls):
cls.driver.quit()
if __name__ == '__main__':
unittest.main(verbosity=2, testRunner= HTMLTestRunner(output= 'reports', report_name= 'hello-world-report'))
Metodos de busqueda:
cls.driver.find_element_by_css_selector()
cls.driver.find_element_by_xpath()
cls.driver.find_element_by_class_name()
cls.driver.find_element_by_class_name()
cls.driver.find_element_by_class_name()
cls.driver.find_element_by_name()
cls.driver.find_element_by_id()
Recomendaciones: usar kite ya que tiene muy buena doc con selenium
me esta encantando este curso
La ruta de los elementos puede cambiar, por lo tanto los xpaths no tienden a ser efectivos a la larga.
La gracia de importar unittest, es que nos ayuda a detectar todo lo que pasa, sobretodo con verbositiy = 2
Como recomendación, a la hora de poner un selector muy largo, con elemento anidados, lo mejor es no dejar espacios y poner el maravilloso: >, igual que en css. div.header-minicart > span.ico
También podemos escribir selectores css dentro de los parámetros del método: find_element_by_css_selector()
Los xpath son muy largos en la mayoría de ocaciones, por lo que no es buena idea utilizarlos siempre.
Dentro del inspector de elementos, tenemos la capacidad de copiar el xpath, en caso de que no haya suficiente especificidad.
Tenemos que tener en cuenta que cada vez que testeamos algo, sin poner el classmethod, abriremos una y otra vez el navegador, ya que cada método, es aislado de otros y por lo tanto es una nueva orden. Cada orden abre y cierra.
Le asignas una variabla a tu búsqueda de elementos para que sea más fácil de manejar.
para que se tome su tiempo podemos añadirle a nuestro objeto de la clase webdriver, el método: implicitly _wait(Tiempo en segundos)
Si queremos hacer que se maximize nuestra ventana, solo tenemos que utilizar el método maximize_window() sobre el objeto de la clase webdriver.
Con nuestro código, también podemos llegar a selecionar específicamente las etiquetas que componen un sitio web. Nuestras formas de lograrlo es mediante: El ID, Nombre del atributo, Nombre de la clase, Nombre de la etiqueta, XPath (ruta de nodos en el xml), selectores de CSS, texto del link, texto parcial del link.
Como se puede encontrar un iframe, dentro de otro iframe, donde su identificador es variable?
Para ubicar el carrito de compras no me sirvio por medio del selector css, utilicé class name de la siguiente forma y me funcionó muy bien:
<@classmethod
def test_shopping_trolli(cls): ## este caso busca elementos por selectores css
shopping = cls.driver.find_element_by_class_name("icon")>
Buscar por XPATH cuando lo sabes usar es lo mas sencillo
Buenas, quería saber si me falto instalar algo para que me entregue los snippets, para poder trabajar o intentar cosas que van más allá del curso necesitaré poder ver las otras opciones y leer sobre estas, gracias
Aqui una pagina para practicar los selectores
https://demoqa.com/elements
Me pregunto cuánto afectara usar styled components para hacer web scraping mediante id, clases, etc.
Aunque también es un buen método para dificultar que hagan esta práctica con nuestra web, supongo…
Al correr el código me sale lo siguiente:
_Ran 0 tests in 0.000s
OK_
No entiendo muy bien porqué, a decir verdad, no sé si sea un error en el código, pero lo dejaré adjunto ante la duda:
import unittest
from selenium import webdriver
from pyunitreport import HTMLTestRunner
class HomePageTests(unittest.TestCase):
def setUp(self):
self.driver = webdriver.CHrome(executable_path = '/home/yanina/Downloads/chromedriver')
driver = self.driver
driver.get("http://demo.onestepcheckout.com/")
driver.maximize_window()
driver.implicitly_wait(15)
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_class_name(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("button")
def test_count_of_promo_banner_images(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('/html/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= 'find-report'))```
Entiendo que este sistema valida los elementos, pero habría una forma de poder guardar los resultados, por ejemplo si con xpath leo los links.
Podría guardarlos en una lista?
ya no sirve ese sitio web.
Me salio un error en la linea del primer Xpath, tuve que quitarle las “” a top y dejarle ’ ’ , para que funcionara.
tengo una duda, en la seccion, aprox en el minuto 7
def test_search_text_field_by_class_name(self):
search_field = self.driver.find_element_by_class_name("input-text")
me da curiosidad como puede funcionar cuando en el HTML el nombre de la clase es “input-test requierd-entry”, o si estoy equivocada, si alguien me puede corregir por favor
voy a insertar el codigo HTML del elemento
<input id="search" type="search" name="q" value="" class="input-text required-entry" maxlength="128" placeholder="Search entire store here..." autocomplete="off">
.assertEqual(): Son validaciones en el codigo para verificar si una accion se cumple o no. Su sintaxis es de la siguiente forma
* Synthax: assertEqual(firstValue, secondValue, message)
* Parametrs: assertEqual() Acepta tres valores, los cuales se explican a continuacion:
* firstValue: Variable de cualquier tipo que se usa para la comparacion de la accion
* secondValue: Variable de cualquier tipo que se usa para la comparacion de la accion
* message: Una cadena de string, que se muestra si el test fue fallido
Para lo que le fallo el caso de prueba test_count_of_promo_banner_images aqui esta la solucion:
def test_count_of_promo_banner_images(self):
banner_list = self.driver.find_elements_by_class_name("promos")
banners = banner_list[0].find_elements_by_tag_name('img')
self.assertEqual(3, len(banners))```
Hola a todos, si Chrome les presenta inconvenientes, les puedo sugerir utilizar firefox como segunda opción, lo único que cambia es el web driver, el resto del código es el mismo.
<import unittest #### Esta libreria permita traer todas la pruebas a realizar
from pyunitreport import HTMLTestRunner #### Esta es la que ejecutará las pruebas
from selenium import webdriver #### Este comunica python con el navegador
class testSuit_search_field(unittest.TestCase):
def setUp(self): #### setUp prepara todo el entorno de trabajo para ejecutar la prueba
self.driver = webdriver.Firefox(executable_path=r'/home/andres/Documents/Platzi/Automatización_Python/geckodriver')
driver = self.driver
driver.get("url here")
driver.maximize_window()
driver.implicitly_wait(20)
def test_search_text_field(self):
search_field = self.driver.find_element_by_id("search")
if __name__ == '__main__':
unittest.main(verbosity=2, testRunner= HTMLTestRunner(output= 'segunda_clase', report_name= 'reporte_segunda_clase'))
>
Hola muy buenas tardes, tengo la siguiente pregunta:
por que al ejecutar la prueba, se cierra el web browser tan pronto como finaliza el test?
<import unittest #### Esta libreria permita traer todas la pruebas a realizar
from pyunitreport import HTMLTestRunner #### Esta es la que ejecutará las pruebas
from selenium import webdriver #### Este comunica python con el navegador
class testSuit_search_field(unittest.TestCase):
def setUp(self): #### setUp prepara todo el entorno de rabajopara ejecutar la prueba
self.driver = webdriver.Chrome(executable_path=r'/home/andres/Documents/Platzi/Automatización_Python/chromedriver')
driver = self.driver
driver.get("weg page")
driver.maximize_window()
driver.implicitly_wait(20)
def test_search_text_field(self):
search_field = self.driver.find_element_by_id("search")
if __name__ == '__main__':
unittest.main(verbosity=2, testRunner= HTMLTestRunner(output= 'segunda_clase', report_name= 'reporte_segunda_clase'))
>
los nombres de las funciones son dados por convecion?.. o realmente tienen que llamarse de una marera específica para que funcionen.
Soy nuevo en Python y Selenium, pero creo que la sentencia para maximizar la ventana debe estar arriba que la sentencia que nos lleva al sitio web, como el profe nos muestra no maximiza la ventana
def setUp(self):
self.driver = webdriver.Chrome(executable_path= r'path_driver') #ejecutar driver de Chrome
driver = self.driver
driver.get("sitio_web")#ir pagina web
driver.maximize_window() #maximizar ventana navegador
driver.implicitly_wait(15)```
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?