No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Demora implícita y explícita

14/24
Recursos

Aportes 33

Preguntas 16

Ordenar por:

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

Si les aparece este error en la terminal:

TypeError: init() takes 2 positional arguments but 3 were given

Es porque la clase element_to_be_located fue llamado con tres argumentos (self implícito, By.LINK_TEXT, y el link del texto) pero solo acepta dos, self (implícito) y una tupla. Esa tupla debe tener como primer elemento el tipo de selector que se va a usar (en este caso By.LINK_TEXT) y como segundo el selector. Por lo tanto el codigo debe quedar así:

account = WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located((By.LINK_TEXT, 'ACCOUNT')))

Lo mismo para todas las lineas similares

Solo hay una cosa que creo que falto decir desde las primeras clases. Los test se ejecutan en orden alfabetico, y si los metodos no tienen la palabra test entonces unittest no los ejecuta.

Hace falta de un curso de Python async

A mi parecer esta clase fue muy intensa vimos mucha sintaxis nueva de golpe sin embargo estuvo cool

Saludos, les dejo el codigo de la clase con notas acerca de las funciones vistas:

import unittest
from selenium import webdriver

#Herramienta para seleccionar elementos de la web con sus selectores
from selenium.webdriver.common.by import By

#Herramienta para hacer uso de las expected conditions y esperas explicitas
from selenium.webdriver.support.ui import WebDriverWait

#Importar esperar explicitas
from selenium.webdriver.support import expected_conditions as EC


class ExplicitWaitTest(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Firefox(executable_path= r'./geckodriver.exe')
        driver = self.driver
        driver.implicitly_wait(10)
        driver.maximize_window()
        driver.get('https://demo-store.seleniumacademy.com/')

    def test_account_link(self): #Cuentas del sitio

        #Esperar 10 segundos hasta que se cumpla la funcion
        WebDriverWait(self.driver, 3).until(lambda s: s.find_element_by_id('select-language').get_attribute('length') == '3')

        #Hacer referencia al enlace donde estan las cuentas
        account = WebDriverWait(self.driver, 3).until(EC.visibility_of_element_located((By.LINK_TEXT, 'ACCOUNT')))
        account.click()


    def test_create_new_customer(self): #Creacion de nuevo usuario

        #Encontrar el elemento por el texto del enlace
        self.driver.find_element_by_link_text('ACCOUNT')

        #Hacer referencia a la cuenta
        my_account = WebDriverWait(self.driver, 3).until(EC.visibility_of_element_located((By.LINK_TEXT, 'My Account')))
        my_account.click()

        #Referencia a crear una cuenta
        create_account = WebDriverWait(self.driver, 2).until(EC.element_to_be_clickable((By.LINK_TEXT, 'CREATE AN ACCOUNT')))
        create_account.click()

        #Verificacion de estado de pagina web
        WebDriverWait(self.driver, 3).until(EC.title_contains('Create New Customer Account'))

    def tearDown(self):
        driver = self.driver
        driver.implicitly_wait(3)
        driver.close()

if __name__ == "__main__":
    unittest.main(verbosity= 2)```

Quede mas conforme con las explicaciones y ejemplos de espera implícita y explicita de esta pagina: https://selenium-python.readthedocs.io/waits.html

Muy mal explicada esta clase… bueno, es que ni siquiera est[a explicando

Esta linea a parte de ser poco entendible para mi creo que es innecesaria para lo que se esta probando con la función test_account_link

WebDriverWait(self.driver, 10).until(lambda s: s.find_element_by_id('select-language').get_attribute('length') == '3')

ya lo que queremos es esperar maximo 10 segundos a que el link ACCOUNT sea visible y hacer click en el y eso se logra con las siguientes dos lineas solamente:

account = WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located((By.LINK_TEXT, 'ACCOUNT')))
account.click()

Acá dejo el código actualizado y funcionando ->2022<-

import unittest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


class ExplicitWaitTests(unittest.TestCase):

    @classmethod
    def setUpClass(cls) -> None:
        s = Service('./chromedriver')
        cls.driver = webdriver.Chrome(service=s)

        driver = cls.driver
        driver.get('http://demo-store.seleniumacademy.com/')
        driver.maximize_window()
        driver.implicitly_wait(3)
    
    def test_account_link(self):
        WebDriverWait(self.driver, 10).until(
                lambda s: s.find_element(
			By.ID,
			'select-language'
			).get_attribute('length') == '3')
        
        account = WebDriverWait(self.driver, 10).until(
                EC.visibility_of_element_located(
			(By.LINK_TEXT, 'ACCOUNT')
			)
                )
        account.click()

    def test_create_new_customer(self):
        text = self.driver.find_element(
		By.LINK_TEXT,
		'ACCOUNT'
		)
        
        my_account = WebDriverWait(self.driver, 10).until(
                EC.visibility_of_element_located((By.LINK_TEXT, 'My Account'))
                )
        my_account.click()

        create_account_button = WebDriverWait(self.driver, 10).until(
                EC.element_to_be_clickable((By.LINK_TEXT, 'CREATE AN ACCOUNT'))
                )
        create_account_button.click()

        WebDriverWait(self.driver, 10).until(
                EC.title_contains('Create New Customer Account')
                )

    @classmethod
    def tearDownClass(cls) -> None:
        cls.driver.quit()


if __name__ == '__main__':
    unittest.main(verbosity=2)

Para utilizar WebcriverWait, tenemos que hacer referencia al navegador instanciado una coma y luego los segundos que se tomará y luego hacemos el uso de until de hasta que o hasta en español. para dar la condición. Tiene sentido, pues se puede leer como: Navegador espera 20 segundos hasta que la página tenga este estado.

Existen dos tipos de demoras: implícita y explícita. La implícita, es aquella que le da un tiempo determinado a Selenium para encontrar por un elemento, Si este no se encuentra en ese tiempo, nos arroja un error. La explícita es aquella crea condiciones para que Selenium espere hasta que se cumplan. De esa forma podemos hacer que espere hasta que finalize algún proceso en la página.

En esta página lo explican todo muy claro.

Sería ideal que se adjuntaran los archivos con el código de cada clase y el PDF con las filminas que se incluye en todos los cursos que he hecho hasta ahora.
Gracias!!!

Vale la pena que consideremos todos que la documentación de Selenium nos alerta:

Warning: Do not mix implicit and explicit waits. Doing so can cause unpredictable wait times. For example, setting an implicit wait of 10 seconds and an explicit wait of 15 seconds could cause a timeout to occur after 20 seconds.

import unittest
from selenium import webdriver

#Herramienta para seleccionar elementos de la web con sus selectores
from selenium.webdriver.common.by import By

#Herramienta para hacer uso de las expected conditions y esperas explicitas
from selenium.webdriver.support.ui import WebDriverWait

#Importar esperar explicitas
from selenium.webdriver.support import expected_conditions as EC


class ExplicitWaitTest(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Firefox(executable_path= r'./geckodriver.exe')
        driver = self.driver
        driver.implicitly_wait(10)
        driver.maximize_window()
        driver.get('https://demo-store.seleniumacademy.com/')

    def test_account_link(self): #Cuentas del sitio

        #Esperar 10 segundos hasta que se cumpla la funcion
        WebDriverWait(self.driver, 3).until(lambda s: s.find_element_by_id('select-language').get_attribute('length') == '3')

        #Hacer referencia al enlace donde estan las cuentas
        account = WebDriverWait(self.driver, 3).until(EC.visibility_of_element_located((By.LINK_TEXT, 'ACCOUNT')))
        account.click()


    def test_create_new_customer(self): #Creacion de nuevo usuario

        #Encontrar el elemento por el texto del enlace
        self.driver.find_element_by_link_text('ACCOUNT')

        #Hacer referencia a la cuenta
        my_account = WebDriverWait(self.driver, 3).until(EC.visibility_of_element_located((By.LINK_TEXT, 'My Account')))
        my_account.click()

        #Referencia a crear una cuenta
        create_account = WebDriverWait(self.driver, 2).until(EC.element_to_be_clickable((By.LINK_TEXT, 'CREATE AN ACCOUNT')))
        create_account.click()

        #Verificacion de estado de pagina web
        WebDriverWait(self.driver, 3).until(EC.title_contains('Create New Customer Account'))

    def tearDown(self):
        driver = self.driver
        driver.implicitly_wait(3)
        driver.close()

if __name__ == "__main__":
    unittest.main(verbosity= 2)

No había logrado entender bien así que recurrí a este enlace donde ese explica este mismo tema, por si alguien quiere profundizar.

Les dejo esta explicación que siento más completa sobre las esperas implícita y explícita: https://www.guru99.com/implicit-explicit-waits-selenium.html

Esta tabla ayuda a identificar mejor cada tipo de waits
url del blog: https://www.guru99.com/implicit-explicit-waits-selenium.html

By nos ayuda para hacer referencia a un elemento del sitio Web a través de sus selectores, NO para identificarlo, ES para interactuar de madera distinta a como lo hace WebDriver.

WebDriverWait nos ayuda para hacer uso de las ExpectedCondition junto con las Esperas Explicitas

![](

Entendido

Asincronismo debilidad de Selenium

las pausas nos ayudan a manejar el asincronismo

demora implicita
busca uno o varios elementos en el DOM si no e encuentran disponibles por la cantidad de tiempo asignado

demora explicita
utiliza condiciones de espera determinada y continuan hasta que se cumplan

codigo

import unittest
from pyunitreport import HTMLTestRunner
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 CompareProducts(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Chrome(executable_path='./chromedriver')
        driver = self.driver
        driver.implicitly_wait(30)
        driver.maximize_window()
        driver.get('https://demo-store.seleniumacademy.com/')


    def test_account(self):
        WebDriverWait(self.driver, 10).until(lambda s: s.find_element_by_id('select-language').get_attribute('length') == '3')

        account = WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located((By.LINK_TEXT, 'ACCOUNT' )))
        account.click()

    def test_create_new_customer(self):
        self.driver.find_element_by_link_text('ACCOUNT').click()

        my_account = WebDriverWait(self.driver,10).until(EC.visibility_of_element_located((By.LINK_TEXT, 'My Account')))
        my_account.click()

        create_account_button = WebDriverWait(self.driver, 20).until(EC.element_to_be_clickable((By.LINK_TEXT, 'CREATE AN ACCOUNT')))
        create_account_button.click()

        WebDriverWait(self.driver,10).until(EC.title_contains(('Create New Custumer Account')))


    def tearDown(self):
        self.driver.close()

if __name__ == '__main__':
    unittest.main(verbosity=2, testRunner= HTMLTestRunner(output= 'reports', report_name= 'hello-world-report'))

por si el combo de idiomas no les aparece ya intente este

import unittest
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 ExplicitWaitTests(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Chrome(executable_path='./chromedriver')
        driver = self.driver
        driver.get("https://demo.onestepcheckout.com/")

    def test_account_link(self):
        WebDriverWait(self.driver, 10).until(lambda s: len(s.find_element_by_xpath(
            '/html/body/div/div[2]/div[2]/div/div/div[2]/ul').find_elements_by_tag_name('li')) == 3)
        account = WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located((By.LINK_TEXT, 'ACCOUNT')))
        account.click()

    def test_create_new_user(self):
        self.driver.find_element_by_link_text('ACCOUNT').click()

        my_account = WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located((By.LINK_TEXT, 'My Account')))
        my_account.click()

        create_account_button = WebDriverWait(self.driver, 20).until(EC.element_to_be_clickable((By.LINK_TEXT, 'CREATE AN ACCOUNT')))
        create_account_button.click()

        WebDriverWait(self.driver, 10).until(EC.title_contains('Create New Customer Account'))

    def tearDown(self):
        self.driver.implicitly_wait(3)
        self.driver.close()


if __name__ == "__main__":
    unittest.main(verbosity=2)

Noten que es interesante que las llamadas a WebDriverWait, como:

WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.LINK_TEXT, 'CREATE AN ACCOUNT')))

Van a retornar el elemento que se está “observando”. Es decir que cuando la condición se cumpla va a retornar lo mismo que:

driver.find_element(By.LINK_TEXT, 'CREATE AN ACCOUNT')

Para poder utilizar nuestras esperas explícitas, solo necesitamos importar By, WebDriverwait y expected_conditions. from selenium.webdriver.common.by import By ; from selenium.webdriver.support.ui import WebDriverWait ; from selenium.webdriver.support import expected_conditions as EC

Las pausas, son importantes para manejar lo que es una de las mayores debilidades de Selenium: el asincronísmo. Sin embargo estas pausas, no se pueden hacer a la loca con sleep.

import unittest
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 ExplicitWaitTest(unittest.TestCase):
    
    def setUp(self):
        self.driver = webdriver.Chrome(executable_path=r'./chromedriver.exe')
        driver = self.driver
        driver.get('http://demo-store.seleniumacademy.com/')
    
    def test_account_link(self):
        
        WebDriverWait(self.driver, 10).until(lambda s: s.find_element_by_id('select-language').get_attribute('length') == '3')
       
        account = WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located((By.LINK_TEXT, 'ACCOUNT')))
        account.click()           
    
    def test_create_new_customer(self):
        self.driver.find_element_by_link_text('ACCOUNT').click()
        
        my_account = WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located((By.LINK_TEXT, 'My Account')))
        my_account.click()
        
        create_account_button = WebDriverWait(self.driver, 20).until(EC.element_to_be_clickable((By.LINK_TEXT, 'CREATE AN ACCOUNT')))
        create_account_button.click()
        
        WebDriverWait(self.driver, 10).until(EC.title_contains('Create New Customer Account'))
    
    def tearDown(self):
        self.driver.close()
        
if __name__ == '__main__':
    unittest.main(verbosity=2)

¡Excelente profesor y muy buenas explicaciones!
A cada vez más me gusta este curso. 😄

Tengo que automatizar el registro de usuarios, por medio de pruebas en Seleniun… alguien me podria dar alguna pautas para que la ejecución del script no tarde tanto tiempo. son 1000 registros

estupendo

Esta clase fue genial, sobre todo porque me di la oportunidad de corregir algunos errores antes que el profesor los hiciera. Me deja muy tranquilo saber que voy por el camino correcto.