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

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

19 Días
11 Hrs
37 Min
45 Seg

Page Object Model (POM)

22/24
Recursos

Aportes 32

Preguntas 14

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

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 attributeopen

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.

**Test\_google.py** ```js import unittest from selenium import webdriver from pyunitreport import HTMLTestRunner from selenium.webdriver.common.by import By from google_page import GooglePage class GoogleTest(unittest.TestCase): @classmethod def setUpClass(cls): chrome_driver_path = r"/chromedriver.exe" cls.driver = webdriver.Chrome() driver = cls.driver driver.implicitly_wait(30) driver.maximize_window() def test_search(self): google = GooglePage(self.driver) google.open() google.search("Platzi") self.assertEqual("Platzi", google.keyword) @classmethod def tearDown(cls) -> None: cls.driver.implicitly_wait(3) cls.driver.close() if __name__ == "__main__": unittest.main(verbosity = 2, testRunner = HTMLTestRunner(output = "reportes", report_name = "select_test_google")) ```import unittestfrom selenium import webdriverfrom pyunitreport import HTMLTestRunnerfrom selenium.webdriver.common.by import Byfrom google\_page import GooglePage class GoogleTest(unittest.TestCase): @classmethod def setUpClass(cls): chrome\_driver\_path = r"/chromedriver.exe" cls.driver = webdriver.Chrome() driver = cls.driver driver.implicitly\_wait(30) driver.maximize\_window() def test\_search(self): google = GooglePage(self.driver) google.open() google.search("Platzi") self.assertEqual("Platzi", google.keyword) @classmethod def tearDown(cls) -> None: cls.driver.implicitly\_wait(3) cls.driver.close() if \_\_name\_\_ == "\_\_main\_\_": unittest.main(verbosity = 2, testRunner = HTMLTestRunner(output = "reportes", report\_name = "select\_test\_google")) **google\_page.py** ```js import unittest from selenium import webdriver from pyunitreport import HTMLTestRunner 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_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 #def test_search_ddt(self, search_value, expected_count): #pass #def tearDown(self) -> None: #self.driver.implicitly_wait(3) #self.driver.close() if __name__ == "__main__": unittest.main(verbosity = 2, testRunner = HTMLTestRunner(output = "reportes", report_name = "select_google_page")) ```import unittestfrom selenium import webdriverfrom pyunitreport import HTMLTestRunnerfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import WebDriverWaitfrom 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\_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 \#def test\_search\_ddt(self, search\_value, expected\_count): #pass \#def tearDown(self) -> None: #self.driver.implicitly\_wait(3) #self.driver.close() if \_\_name\_\_ == "\_\_main\_\_": unittest.main(verbosity = 2, testRunner = HTMLTestRunner(output = "reportes", report\_name = "select\_google\_page"))

google_page.py

Una sub-clase de Object que contiene los métodos y los parámetros necesarios para interactuar con esa página.

test_google.py

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