En el código al parecer falto invocar el click_submit
con paréntesis, ya que sin paréntesis se cierra sin que aparezca los resultados de búsqueda.
def search(self, keyword):
self.type_search(keyword)
self.click_submit()
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
Convierte tus certificados en títulos universitarios en USA
Antes: $249
Paga en 4 cuotas sin intereses
Termina en:
Héctor Vega
Aportes 32
Preguntas 14
En el código al parecer falto invocar el click_submit
con paréntesis, ya que sin paréntesis se cierra sin que aparezca los resultados de búsqueda.
def search(self, keyword):
self.type_search(keyword)
self.click_submit()
De entrada no entendía como es que este modelo nos da los beneficios que se mencionan en la clase. Investigando por ahí entendí que es hacer un objeto que represente la página y hacer los test contra el objeto; así si la página se modifica sólo tendrás que modificar el objeto y todos los test quedarían igual.
Si no se usa este método y haces un montón de tests para el sitio es muy probable que los test queden de tal manera que funcionen sólo para la página de una manera y si la página cambia tendrías que estar actualizando todos los test de uno por uno y eso va a consumir mucho más tiempo que a si utilizaras correctamente el modelo de POM
Page Object Model es un patrón de diseño utilizado en Testing, el cual, tiene beneficios para la elaboración de Tests.
Funcionamiento:
-En vez de tener nuestros Test en un solo archivo, los tendremos abstraídos en una nueva capa llamada Pages, donde tendremos los Tests en archivos independientes, haciendo referencia al sitio donde se aplica (Home, Login, etc).
A los archivos independientes se les agregará un nuevo archivo que es el Page Object, el cual se encargará de tomar los Tests que se están realizando y validarlas contra los Tests Cases.
Creo que he usado POM sin saberlo? curioso…🤔
Estaria bueno que muestres tambien Page Factory
En los metodos de google_page.py, les recomiendo que usen la propiedad
self.search_locator
En lugar de directamente la ‘q’. Por ejemplo:
input_field = self._driver.find_element_by_name(self.search_locator)
Asi si tiene que buscar el elemento por el que buscan no tiene que cambiarlo en todas partes.
Saludos amigos hice el ejercicio en Firefox aqui les comparto el codigo:
|
Test_google . py
import unittest
from selenium import webdriver
from google_page import Google
class GoogleTest(unittest.TestCase):
@classmethod#Decoradores para correr en una sola instancia del navegador
def setUpClass(cls):
cls.driver = webdriver.Firefox(executable_path= r'./geckodriver.exe')
def test_search(self):
google = Google(self.driver)
google.open()
google.search('Python')
self.assertEqual('Python', google.keyword)
@classmethod
def tearDownClass(cls):
cls.driver.close()
if __name__ == '__main__':
unittest.main()
google_page .py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class Google(object):
def __init__(self,driver):
self._driver = driver
self._url = 'https://google.com'
self.search_locator = 'q'
@property #Propiedad para busqueda
def is_loaded(self):
WebDriverWait(self._driver , 10).until(EC.presence_of_element_located((By.NAME, 'q')))
return True
@property
def keyword(self):
input_field = self._driver.find_element_by_name('q')
return input_field.get_attribute('value')
def open(self):
self._driver.get(self._url)
def type_search(self, keyword):
input_field = self._driver.find_element_by_name('q')
input_field.send_keys(keyword)
def click_submit(self):
button_submit = self._driver.find_element_by_xpath('/html/body/div[1]/div[3]/form/div[2]/div[1]/div[1]/div/div[1]/div/span/svg')
button_submit.click()
def search(self, keyword):
self.type_search(keyword)
self.click_submit
Otra clase que me hizo sudar y sacar lo mejor de mí. Muchas gracias Héctor.
Excelente clase! Buena explicación.
Hola!, este es mo codigo de la clase
test_google.py
import unittest
from selenium import webdriver
from google_page import GooglePage
class GoogleTest(unittest.TestCase):
@classmethod # para que corran en una sola instancia del navegador
def setUp(cls):
cls.driver = webdriver.Chrome(executable_path=r'C:\Users\kren1\Documents\curso\Python_con_Selenium\chromedriver.exe')
def test_search(self):
google = GooglePage(self.driver)
google.open()
google.search('Platzi')
self.assertEqual('Platzi', google.keyword)
@classmethod
def tearDownClass(cls):
cls.driver.close()
if __name__ =="__main__":
unittest.main(verbosity=2)
google_page.py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class GooglePage(object):
def __init__(self,driver):
self._driver = driver
self._url = 'https://google.com'
self.search_locate = 'q'
@property
def is_located(self):
WebDriverWait(self._driver, 10).until(EC.presence_of_all_elements_located((By.NAME, 'q')))
return True
@property
def keyword(self):
input_field = self._driver.find_element_by_name('q')
return input_field.get_attribute('value')
def open(self):
self._driver.get(self._url)
def type_search(self,keyword):
input_field = self._driver.find_element_by_name('q')
input_field.send_keys(keyword)
def click_submit(self):
input_field = self._driver.find_element_by_name('q')
input_field.submit()
def search(self, keyword):
self.type_search(keyword)
self.click_submit()
En vez de manejar las pruebas en solo archivo, se manejan pruebas inpendientes. Cada uno de estos archivos, se les llaman pages, haciendo referencia. al sitio en dónde se aplican.Creamos una por ejemplo, para el home, para el login, para el signup. A los archivos de todo el sitio web, creamos una capa de abstracción. Esto último lo logramos con otro archivo: El Page Object. El que se encargará de tomar las pruebas que se están realizando, para validarlas con los Test Cases.
Hola yo tenia un problema que cuando escribe el termino la barra de google despliega como varios resultados y no hace el submit, lo resolvi de esta forma
espero le sirva a alguien
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class GooglePage(object):
def __init__(self, driver):
self._driver = webdriver.Chrome(executable_path='./chromedriver')
self._url = 'https://google.com '
self.search_locator = 'q'
@property
def is_loaded(self):
WebDriverWait(self._driver, 10).until(EC.presence_of_element_located((By.NAME, 'q')))
return True
@property
def keyword(self):
input_field = self._driver.find_element_by_name('q')
return input_field.get_attribute('value')
def open(self):
self._driver.get(self._url)
def type_search(self, keyword):
input_field = self._driver.find_element_by_name('q')
input_field.send_keys(keyword)
#buscando el logo y dandole click no dejamos que eso aparezca
self._driver.find_element_by_xpath('//*[@id="hplogo"]').click()
def click_submit(self):
input_field = self._driver.find_element_by_name('q')
input_field.submit()
def search(self, keyword):
self.type_search(keyword)
#y luego dandole click al boton de busqueda
self._driver.find_element_by_xpath('//*[@id="tsf"]/div[2]/div[1]/div[3]/center/input[1]').click()
Si al momento de ejecutar el código les aparece el error:
AttributeError: ‘GooglePage’ object has no attribute ‘open’
Deben fijarse en la identación de sus metodos en el archivo
google_page.py
Puede que todos los métodos estén al interior del constructor:
def __init__(self, driver):
En cuyo caso simplemente deben eliminar la identación desde el primer decorador en adelante
@property
def is_loaded(self):
De esta manera se garantiza el acceso a los metodos en el archivo
google_test.py
Espero que les funcione como en mi caso. Saludos!!!
Pues parece una POO, donde los objetos son Pages
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class GooglePage(object):
def __init__(self, driver):
self._driver = driver
self._url = 'https://google.com'
self.search_locator = 'q'
@property
def is_loaded(self):
WebDriverWait(self._driver, 10).until(
EC.presence_of_element_located((By.NAME, 'q')))
return True
@property
def keyword(self):
input_field = self._driver.find_element_by_name('q')
return input_field.get_attribute('value')
def open(self):
self._driver.get(self._url)
def type_search(self, keyword):
input_field = self._driver.find_element_by_name('q')
input_field.send_keys(keyword)
def click_submit(self):
input_field = self._driver.find_element_by_name('q')
input_field.submit()
def search(self, keyword):
self.type_search(keyword)
self.click_submit
import unittest
from selenium import webdriver
from google_page import GooglePage
class GoogleTest(unittest.TestCase):
@classmethod
def setUp(cls):
cls.driver = webdriver.Chrome(executable_path='../chromedriver')
def test_search(self):
google = GooglePage(self.driver)
google.open()
google.search('Platzi')
self.assertEqual('Platzi', google.keyword)
@classmethod
def tearDown(cls):
cls.driver.close()
if __name__ == "__main__":
unittest.main(verbosity=2)
El page object Model, es un patrón de diseño utilizado en testing. Que nos brindan ventajas en nuestras automatizaciones.
Estaba teniendo un error desde hace 3 dias para que se corriera este codigo.
La verdad estaba 100% perdido y no encontre un comentario que me ayudara.
Pensaba que era algun typo del codigo, pero despues de horas de revisar y comparar el codigo no encontraba la solucion. Intente correr los scripts de clases pasadas y extrañamente tampoco funcionaban. Asi que utilice los reportes de HTML para tener una forma mas amigable de leer el error.
Al final resulto ser que el webdriver estaba desactualizado, asi que unicamente volviendo a instalar el driver se soluciono, espero que a alguien mas le ayude este comentario.
Una sub-clase de Object que contiene los métodos y los parámetros necesarios para interactuar con esa página.
Un documento central que contiene los argumentos para realizar los test.
genial c:
Los beneficios del POM: Se crea un alto nivel de abstracción, para minimizar cambios en las pruebas, en caso de que el sitio se vea modificado. El código solo se tiene que modificar en un solo archivo, lo que lo hace muy administrable.Es un deisño muy legible y flexible.
sinceramente el slide con el gráfico que muestra no es para nada claro…
Muy bien!!!. Gracias
Por lo que veo esta haciendo una refactorizacion del codigo para no repetir tanto
Les recomiendo mucho tomar este curso https://platzi.com/clases/ingenieria-datos/ donde se aplica Page Object Model para para hacer un scraper
Le agregue el uso de la propiedad “is_loaded” y verifique con el primer resultado.
def test_search(self):
google = GooglePage(self.driver)
google.open()
if google.is_loaded:
google.search('lol')
first_result = self.driver.find_element_by_xpath('//*[@id="rso"]/div[1]/div/div/div[1]/a/h3')
self.assertEqual('league of legends', first_result.text.lower())
Excelente
el input_field lo coloque en el init como self.input_field y no llamarlo a cada momento en cada función
Que buena clase Héctor! excelente curso, me gusta mucho como explicas y que todo el código lo escribes limpio y en ingles como todo un buen dev, muchas gracias
y así mismo se aprende día a dia u.u
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?