search
CursosEmpresasBlogLiveConfPrecios
Curso de Automatización de Test con Playwright

Testing de Funcionalidades en Tiendas en Línea

Curso de Automatización de Test con Playwright

Contenido del curso

Fundamentos

  • 1
    Automatización de Pruebas con Playwright: Curso Completo

    Automatización de Pruebas con Playwright: Curso Completo

    05:04 min
  • 2
    Instalación de Playwright en Visual Studio Code

    Instalación de Playwright en Visual Studio Code

    04:08 min
  • 3
    Creación de Tests Automatizados con Playwright en Visual Studio Code

    Creación de Tests Automatizados con Playwright en Visual Studio Code

    05:23 min
  • 4
    Ejecución de Tests con Playwright: Métodos y Configuración

    Ejecución de Tests con Playwright: Métodos y Configuración

    14:35 min

Estructura de un test

  • 5
    Locators y Selectors en Playwright: Uso y Corrección de Errores

    Locators y Selectors en Playwright: Uso y Corrección de Errores

    18:32 min
  • 6
    Uso de Selectores en Tests de UI con Playwright

    Uso de Selectores en Tests de UI con Playwright

    11:24 min
  • 7
    Assertions en Playwright con expect

    Assertions en Playwright con expect

    13:47 min

Reto #1

  • 8
    Testing de Funcionalidades en Tiendas en Línea

    Testing de Funcionalidades en Tiendas en Línea

    Viendo ahora
  • 9
    Flujo de compra completo con Playwright

    Flujo de compra completo con Playwright

    28:43 min

Debug de un test

  • 10
    Depuración de Tests con Playwright Inspector

    Depuración de Tests con Playwright Inspector

    10:27 min
  • 11
    Debugging de selectores con DevTools en Playwright

    Debugging de selectores con DevTools en Playwright

    08:17 min
  • 12
    Debugging API logs en Playwright desde la terminal

    Debugging API logs en Playwright desde la terminal

    04:23 min
  • 13
    Playwright Tracing para depurar tests fallidos

    Playwright Tracing para depurar tests fallidos

    10:41 min

Reto #2

  • 14
    Repara 3 tests rotos en Playwright

    Repara 3 tests rotos en Playwright

    02:05 min
  • 15
    Resolución de Errores en Tests de Playwright

    Resolución de Errores en Tests de Playwright

    15:37 min
  • 16
    toHaveAttribute en lugar de toHaveText

    toHaveAttribute en lugar de toHaveText

    09:09 min

Recomendaciones finales

  • 17
    Recomendaciones finales para tests con Playwright

    Recomendaciones finales para tests con Playwright

    03:30 min
schoolTomar examen

Testing de Funcionalidades en Tiendas en Línea

Platzi DayPlatzi Day

Todos los cursos GRATIS

Se acaba en:
03díasd:12hrsh:27minm:53segs

Escuelas

  • Desarrollo Web
    • Fundamentos del Desarrollo Web Profesional
    • Diseño y Desarrollo Frontend
    • Desarrollo Frontend con JavaScript
    • Desarrollo Frontend con Vue.js
    • Desarrollo Frontend con Angular
    • Desarrollo Frontend con React.js
    • Desarrollo Backend con Node.js
    • Desarrollo Backend con Python
    • Desarrollo Backend con Java
    • Desarrollo Backend con PHP
    • Desarrollo Backend con Ruby
    • Bases de Datos para Web
    • Seguridad Web & API
    • Testing Automatizado y QA para Web
    • Arquitecturas Web Modernas y Escalabilidad
    • DevOps y Cloud para Desarrolladores Web
  • English Academy
    • Inglés Básico A1
    • Inglés Básico A2
    • Inglés Intermedio B1
    • Inglés Intermedio Alto B2
    • Inglés Avanzado C1
    • Inglés para Propósitos Específicos
    • Inglés de Negocios
  • Marketing Digital
    • Fundamentos de Marketing Digital
    • Marketing de Contenidos y Redacción Persuasiva
    • SEO y Posicionamiento Web
    • Social Media Marketing y Community Management
    • Publicidad Digital y Paid Media
    • Analítica Digital y Optimización (CRO)
    • Estrategia de Marketing y Growth
    • Marketing de Marca y Comunicación Estratégica
    • Marketing para E-commerce
    • Marketing B2B
    • Inteligencia Artificial Aplicada al Marketing
    • Automatización del Marketing
    • Marca Personal y Marketing Freelance
    • Ventas y Experiencia del Cliente
    • Creación de Contenido para Redes Sociales
  • Inteligencia Artificial y Data Science
    • Fundamentos de Data Science y AI
    • Análisis y Visualización de Datos
    • Machine Learning y Deep Learning
    • Data Engineer
    • Inteligencia Artificial para la Productividad
    • Desarrollo de Aplicaciones con IA
    • AI Software Engineer
  • Ciberseguridad
    • Fundamentos de Ciberseguridad
    • Hacking Ético y Pentesting (Red Team)
    • Análisis de Malware e Ingeniería Forense
    • Seguridad Defensiva y Cumplimiento (Blue Team)
    • Ciberseguridad Estratégica
  • Liderazgo y Habilidades Blandas
    • Fundamentos de Habilidades Profesionales
    • Liderazgo y Gestión de Equipos
    • Comunicación Avanzada y Oratoria
    • Negociación y Resolución de Conflictos
    • Inteligencia Emocional y Autogestión
    • Productividad y Herramientas Digitales
    • Gestión de Proyectos y Metodologías Ágiles
    • Desarrollo de Carrera y Marca Personal
    • Diversidad, Inclusión y Entorno Laboral Saludable
    • Filosofía y Estrategia para Líderes
  • Diseño de Producto y UX
    • Fundamentos de Diseño UX/UI
    • Investigación de Usuarios (UX Research)
    • Arquitectura de Información y Usabilidad
    • Diseño de Interfaces y Prototipado (UI Design)
    • Sistemas de Diseño y DesignOps
    • Redacción UX (UX Writing)
    • Creatividad e Innovación en Diseño
    • Diseño Accesible e Inclusivo
    • Diseño Asistido por Inteligencia Artificial
    • Gestión de Producto y Liderazgo en Diseño
    • Diseño de Interacciones Emergentes (VUI/VR)
    • Desarrollo Web para Diseñadores
    • Diseño y Prototipado No-Code
  • Contenido Audiovisual
    • Fundamentos de Producción Audiovisual
    • Producción de Video para Plataformas Digitales
    • Producción de Audio y Podcast
    • Fotografía y Diseño Gráfico para Contenido Digital
    • Motion Graphics y Animación
    • Contenido Interactivo y Realidad Aumentada
    • Estrategia, Marketing y Monetización de Contenidos
  • Desarrollo Móvil
    • Fundamentos de Desarrollo Móvil
    • Desarrollo Nativo Android con Kotlin
    • Desarrollo Nativo iOS con Swift
    • Desarrollo Multiplataforma con React Native
    • Desarrollo Multiplataforma con Flutter
    • Arquitectura y Patrones de Diseño Móvil
    • Integración de APIs y Persistencia Móvil
    • Testing y Despliegue en Móvil
    • Diseño UX/UI para Móviles
  • Diseño Gráfico y Arte Digital
    • Fundamentos del Diseño Gráfico y Digital
    • Diseño de Identidad Visual y Branding
    • Ilustración Digital y Arte Conceptual
    • Diseño Editorial y de Empaques
    • Motion Graphics y Animación 3D
    • Diseño Gráfico Asistido por Inteligencia Artificial
    • Creatividad e Innovación en Diseño
  • Programación
    • Fundamentos de Programación e Ingeniería de Software
    • Herramientas de IA para el trabajo
    • Matemáticas para Programación
    • Programación con Python
    • Programación con JavaScript
    • Programación con TypeScript
    • Programación Orientada a Objetos con Java
    • Desarrollo con C# y .NET
    • Programación con PHP
    • Programación con Go y Rust
    • Programación Móvil con Swift y Kotlin
    • Programación con C y C++
    • Administración Básica de Servidores Linux
  • Negocios
    • Fundamentos de Negocios y Emprendimiento
    • Estrategia y Crecimiento Empresarial
    • Finanzas Personales y Corporativas
    • Inversión en Mercados Financieros
    • Ventas, CRM y Experiencia del Cliente
    • Operaciones, Logística y E-commerce
    • Gestión de Proyectos y Metodologías Ágiles
    • Aspectos Legales y Cumplimiento
    • Habilidades Directivas y Crecimiento Profesional
    • Diversidad e Inclusión en el Entorno Laboral
    • Herramientas Digitales y Automatización para Negocios
  • Blockchain y Web3
    • Fundamentos de Blockchain y Web3
    • Desarrollo de Smart Contracts y dApps
    • Finanzas Descentralizadas (DeFi)
    • NFTs y Economía de Creadores
    • Seguridad Blockchain
    • Ecosistemas Blockchain Alternativos (No-EVM)
    • Producto, Marketing y Legal en Web3
  • Recursos Humanos
    • Fundamentos y Cultura Organizacional en RRHH
    • Atracción y Selección de Talento
    • Cultura y Employee Experience
    • Gestión y Desarrollo de Talento
    • Desarrollo y Evaluación de Liderazgo
    • Diversidad, Equidad e Inclusión
    • AI y Automatización en Recursos Humanos
    • Tecnología y Automatización en RRHH
  • Finanzas e Inversiones
    • Fundamentos de Finanzas Personales y Corporativas
    • Análisis y Valoración Financiera
    • Inversión y Mercados de Capitales
    • Finanzas Descentralizadas (DeFi) y Criptoactivos
    • Finanzas y Estrategia para Startups
    • Inteligencia Artificial Aplicada a Finanzas
    • Domina Excel
    • Financial Analyst
    • Conseguir trabajo en Finanzas e Inversiones
  • Startups
    • Fundamentos y Validación de Ideas
    • Estrategia de Negocio y Product-Market Fit
    • Desarrollo de Producto y Operaciones Lean
    • Finanzas, Legal y Fundraising
    • Marketing, Ventas y Growth para Startups
    • Cultura, Talento y Liderazgo
    • Finanzas y Operaciones en Ecommerce
    • Startups Web3 y Blockchain
    • Startups con Impacto Social
    • Expansión y Ecosistema Startup
  • Cloud Computing y DevOps
    • Fundamentos de Cloud y DevOps
    • Administración de Servidores Linux
    • Contenerización y Orquestación
    • Infraestructura como Código (IaC) y CI/CD
    • Amazon Web Services
    • Microsoft Azure
    • Serverless y Observabilidad
    • Certificaciones Cloud (Preparación)
    • Plataforma Cloud GCP

Platzi y comunidad

  • Platzi Business
  • Live Classes
  • Lanzamientos
  • Executive Program
  • Trabaja con nosotros
  • Podcast

Recursos

  • Manual de Marca

Soporte

  • Preguntas Frecuentes
  • Contáctanos

Legal

  • Términos y Condiciones
  • Privacidad
  • Tyc promociones
Reconocimientos
Reconocimientos
Logo reconocimientoTop 40 Mejores EdTech del mundo · 2024
Logo reconocimientoPrimera Startup Latina admitida en YC · 2014
Logo reconocimientoPrimera Startup EdTech · 2018
Logo reconocimientoCEO Ganador Medalla por la Educación T4 & HP · 2024
Logo reconocimientoCEO Mejor Emprendedor del año · 2024
De LATAM conpara el mundo
YoutubeInstagramLinkedInTikTokFacebookX (Twitter)Threads

Hola, llegó el momento de enfrentar tu primer reto. Pero antes un ⚠️ ANUNCIO IMPORTANTE ⚠️

Desafortunadamente, el sitio web con el que resolveré el reto en la siguiente clase no está disponible por el momento. Pero no te preocupes, la consigna es “nunca pares de aprender”, así que te dejo esta web para que realices tus test: https://automationexercise.com/category_products

¿Qué diferencias vas a encontrar respecto a la forma yo resolveré el reto en la siguiente clase?

  • Al hacer hover sobre un artículo a comprar no te aparecerá "quick view", en vez de eso deberás dar click directamente en "view product".
  • Una vez ahí, la cantidad de productos a añadir se tendría que testear de forma distinta. Una pista es que observes el input para la cantidad de prendas en vez de 'button-plus' como yo lo hice.
  • Deberás omitir el paso de seleccionar el tamaño de la prenda, ya que la web que estarás probando no tiene esa opción.
  • Al verificar que el modal y el texto aparecen, en vez del texto "Success" simplemente usa el texto "Added!"

En resumen, podrás realizar 7 de los 9 test del reto, 2 de ellos con los ajustes mencionados arriba (❗):

tests-reto.png

Espero que superes este reto utilizando el ejemplo de la siguiente clase y todo lo que hemos aprendido hasta ahora. Déjame en los comentarios de la siguiente clase cómo quedó tu código y si lograste hacer testing al elemento para incrementar el número de prendas 😉.

Comentarios43

Irving Juárez

Irving Juárez

Estudiante
Hace 4 años
Mauro Mascheroni

Mauro Mascheroni

Estudiante
Hace 4 años
Douglas Lovera

Douglas Lovera

Estudiante
Hace 4 años
Ivan Martinez Calcaño

Ivan Martinez Calcaño

Estudiante
Hace 5 meses•editado
    Elihu Garcia

    Elihu Garcia

    Estudiante
    Hace 3 meses•editado
Jennyfer Tatiana Ramirez Ruiz

Jennyfer Tatiana Ramirez Ruiz

Estudiante
Hace un año
Aitor Reguillaga Otaño

Aitor Reguillaga Otaño

Estudiante
Hace 4 años
Michell gonzalez

Michell gonzalez

Estudiante
Hace 2 meses
Miguel Stiven Herrera Gomez

Miguel Stiven Herrera Gomez

Estudiante
Hace 2 meses•editado
Ismael Ávila Ojeda

Ismael Ávila Ojeda

Estudiante
Hace 4 meses•editado
Diego Padovani

Diego Padovani

Estudiante
Hace 4 meses
Lennys Cantero

Lennys Cantero

Estudiante
Hace 5 meses
Cynthia Sotelo

Cynthia Sotelo

Estudiante
Hace 5 meses
YEIMY ROCIO FUQUEN AVILA

YEIMY ROCIO FUQUEN AVILA

Estudiante
Hace 5 meses
Darlinson Felipe Polania Camacho

Darlinson Felipe Polania Camacho

Estudiante
Hace 5 meses
Leonardo Buezo

Leonardo Buezo

Estudiante
Hace 5 meses
Felipe Madrigal

Felipe Madrigal

Estudiante
Hace 6 meses
fabian marentes

fabian marentes

Estudiante
Hace 7 meses
Juan Aguilera

Juan Aguilera

Estudiante
Hace 7 meses
Camilo Jiménez

Camilo Jiménez

Estudiante
Hace 7 meses•editado
Luis Antonio Del Rio Salguero

Luis Antonio Del Rio Salguero

Estudiante
Hace 8 meses

Hice un tutorial de como hacer este reto, para que comparen soluciones y aprendamos de las contribuciones de cada quien: SOLUCION AL RETO

Una solución o salida rápida que encontre para manejar la publicidad fue recargar la página con el comando page.reload(), esto nos lleva nuevamente a la pagina del home, por lo que se debe hacer click nuevamente al primer producto, por lo que esta vez nos lleva al producto, sin salir la publicidad.

Muy probablemente falle porque la página muestra publicidad, cuidado con eso 😬

Solución del RETO 1 usando el site:

import { test, expect } from '@playwright/test'; test('add product to shopping cart', async({ page })=>{ //prevent ads from popping up in https://automationexercise.com/ await page.route('**/*', route => { const url = route.request().url(); if (url.match(/google-vignette/)) { return route.abort(); } route.continue(); }); //navigate to site await page.goto('https://automationexercise.com/'); //validate title await expect(page).toHaveTitle('Automation Exercise'); //navigate to Products page const productsLink = page.locator('ul.nav.navbar-nav a:has-text("Products")'); await expect(productsLink).toBeVisible(); await productsLink.click(); //select first product and go to product details const firstProduct = page.locator('ul.nav.nav-pills a:has-text("View Product")').first(); await expect(firstProduct).toBeVisible(); await firstProduct.click() //add 3 items of the selected product const quantityInput = page.locator('input#quantity'); await quantityInput.fill('3'); //validate input element shows 3 items const inputValue = await quantityInput.inputValue(); expect(inputValue).toBe('3'); //add items to cart const addItemsButton = page.locator('button.btn.btn-default.cart'); await expect(addItemsButton).toBeVisible(); await addItemsButton.click(); //continue shopping await expect(page.locator('#cartModal')).toBeVisible(); const continueShoppingButton = page.locator('#cartModal .btn.btn-success.close-modal.btn-block'); await expect(continueShoppingButton).toBeVisible() await continueShoppingButton.click(); })

Buena aportación! los ads no me dejaban avanzar pero con tu ejemplo pude hacer mi propio ad blocker jaja solo que no me funcionó utilizando '/google-vignette/' sino '/googleads/' 👍

in my case i created to files one is runner and other is pages but i created it vey bad 'cause i should to create one for one page and for diferentes fron-ents but here is my work

Aupa! He estado practicado con este reto y quiero compartiros mi propuesta. Se agradecen sugerencias.

Saludos!

const SELECTED_PRODUCT = "Rs. 700"; const NUMBER_OFF_UNITS = "10"; test(`I add ${SELECTED_PRODUCT} "${SELECTED_PRODUCT}" model polo and proced to check out`, async ({ page }) => { await page.goto('https://automationexercise.com/'); await page.mouse.wheel(0, 500); await page.locator("a[href='/products']").click(); // This code evited the google ads page if( page.url() === "https://automationexercise.com/#google_vignette"){ await page.frameLocator('iframe[name="aswift_5"]').getByRole('button', { name: 'Close ad' }).click(); } // Navigate to Polo section and choose 'Rs. 700' polo await page.locator("a[href='/brand_products/Polo']").click(); let selectedProductWrapper = page.locator(`div.product-image-wrapper:has-text(' ${SELECTED_PRODUCT}')`); await selectedProductWrapper.hover(); await selectedProductWrapper.locator(".choose a").click(); // ADD 10 polo to the card await page.locator("#quantity").fill(NUMBER_OFF_UNITS); await page.locator("button.cart").click(); await expect(page.locator(".modal-content")).toBeVisible(); await expect(page.locator(".modal-title.w-100")).toHaveText("Added!"); // Confirm the card await page.locator(".modal-content a").click(); await expect(page.locator("tr#product-8 td.cart_quantity button")).toHaveText(NUMBER_OFF_UNITS); // Check out await page.locator("a.check_out").click(); await expect(page.locator(".modal-content")).toBeVisible(); await page.locator(".modal-content a").click(); }
import { test, expect } from '@playwright/test'; test('Agregar producto', async ({ page }) => { await page.goto('https://automationexercise.com/'); await page.getByRole('link', { name: 'View Product' }).first().click(); await page.locator('#quantity').fill('3'); await page.getByRole('button', { name: 'Add to cart' }).click(); await expect(page.getByText('ADDED!')).toBeVisible(); await page.getByRole('button', { name: 'Continue Shopping' }).click(); await expect(page.locator('div.modal-content')).not.toBeVisible(); });

Adjunto la solucion del reto

import { test, expect } from '@playwright/test'; test('first activity', async ({ page }) => { await page.goto('https://automationexercise.com/'); await page.locator('.features_items').hover(); await page.getByRole('link', { name: 'View Product' }).first().click(); await expect(page.locator('#quantity')).toBeVisible(); await page.locator('#quantity').fill('3'); await page.getByRole('button', { name: 'Add to cart' }).click(); await expect(page.locator('.modal-content')).toBeVisible(); await expect(page.getByRole('heading', { name: 'Added!' })).toHaveText('Added!'); await page.getByRole('button', { name: 'Continue Shopping' }).click(); await expect(page.locator('.modal-content')).not.toBeVisible(); });

Mi código:

import { test, expect } from '@playwright/test';test('test', async ({ page }) { //abrir en el navegador la tienda virtual/ await page.goto('https://automationexercise.com/'); await page.getByRole('button', { name: 'Consent' }).click(); //Deslizar hasta ver los productos/ await expect(page.getByRole('heading', { name: 'features items'})).toBeVisible(); //Hacer click en "View Product" del primer producto/ await page.getByRole('link', { name: 'View Product'}).first().click(); await page.locator('iframe[name="aswift_3"]').contentFrame().getByRole('button', { name: 'Close ad' }).click(); //Añadir 3 productos al carrito/ await page.locator('#quantity').fill(''); await page.locator('#quantity').fill('3'); //Hacer click en añadir al carrito/ await page.getByRole("button",{name: 'Add to cart'}).click(); //Verificar que aparece el modal y el texto de "Added!"/ await expect(page.getByRole('heading', {name: 'Added!'})).toBeVisible(); //Hacer click en el botón "Continue Shopping"/ await page.getByRole('button', { name: 'Continue Shopping' }).click(); //Verificar que el modal ya no es visible/ await expect(page.getByRole('heading', {name: 'Added!'})).not.toBeVisible();});

mi codigo

import { test, expect } from '@playwright/test';

test('Reto Platzi: Flujo completo de compra', async ({ page }) => {

// 1. Abre en el navegador la tienda virtual

await page.goto('https://automationexercise.com/');

await expect(page).toHaveTitle(/Automation Exercise/);

// 2. Desliza hasta ver los productos

// Usamos scrollIntoView para asegurar que el título de productos sea visible

const productTitle = page.getByRole('heading', { name: 'Features Items' });

await productTitle.scrollIntoViewIfNeeded();

await expect(productTitle).toBeVisible();

// 3. Haz click en "Ver más detalles" del primer producto

// Nota: En esta web el botón se llama "View Product"

await page.getByRole('link', { name: 'View Product' }).first().click();

// 4. Usa el botón (+) para añadir 3 productos al carrito

// En esta web se edita el número directamente en el input

const quantityInput = page.locator('#quantity');

await quantityInput.fill('3');

await expect(quantityInput).toHaveValue('3');

// 5. Elige el tamaño del producto

// Nota: Si el producto no tiene tamaño, este paso se puede omitir o

// usar un selector si existiera (ejemplo: page.getByLabel('Size').selectOption('M'))

// Para este ejercicio, validaremos que estamos en la página de detalle.

await expect(page).toHaveURL(/.*product_details/);

// 6. Haz click en Añadir al carrito

await page.getByRole('button', { name: 'Add to cart' }).click();

// 7. Verifica que el modal y el texto de "Success" aparece

// El modal en esta web tiene el ID #cartModal

const modal = page.locator('#cartModal');

await expect(modal).toBeVisible();

await expect(modal).toContainText('Added!');

await expect(modal.getByText('Your product has been added to cart.')).toBeVisible();

// 8. Haz click en el botón de "Continue Shopping"

await page.getByRole('button', { name: 'Continue Shopping' }).click();

// 9. Verifica que el modal ya no es visible

await expect(modal).toBeHidden();

});

import { test, expect } from '@playwright/test';

test('test', async ({ page }) => {

   //1- abre en el navegador la tienda virtual.

  await page.goto('https://automationexercise.com/');

  //desliza hasta ver los productos y hacer click

     await page.locator('a[href="/products"]').click();

   // ver mas detalles del producto 1

    await page.locator('a[href="/product_details/1"]').click();

  //seleccionar 3 productos al carrito

  await page.locator('#quantity').fill('3');

 // agregar al carrito

    await page.locator('button.cart').click();

    // validar que el modal aprezca

    await expect(page.locator('#cartModal')).toBeVisible();

    // continuar comprando

    await page.locator('.btn.btn-success.close-modal.btn-block').click();

    // verifiacar que el modal se haya cerrado

    await expect(page.locator('#cartModal')).not.toBeVisible();

});

Mi solución:

import { test, expect } from "@playwright/test";

test("Probar mi primera compra en la tienda", async ({ page }) => {

// 1. Entramos a la página principal

await page.goto("https://automationexercise.com/");

// 2. Bajamos un poco para ver los productos (scroll)

await page.mouse.wheel(0, 500);

const tituloProductos = page.getByRole("heading", { name: "FEATURES ITEMS" });

await expect(tituloProductos).toBeVisible();

// 3. Click en el primer producto que aparece para ver el detalle

await page.getByRole("link", { name: "View Product" }).first().click();

// 4. Cambiamos la cantidad a 3 productos

// Uso fill para escribir el número directamente en el cuadrito

await page.locator("#quantity").fill("3");

// 5. TODO: No encontré la opción de elegir tamaño en esta página

// 6. Click en el botón de añadir al carrito

await page.getByRole("button", { name: "Add to cart" }).click();

// 7. Verificamos que aparezca el cartel de "Added!" y el mensaje de éxito

await expect(page.getByText("Added!")).toBeVisible();

await expect(page.getByText("Your product has been added to cart.")).toBeVisible();

// 8. Click en "Continue Shopping" para cerrar el aviso

await page.getByRole("button", { name: "Continue Shopping" }).click();

// 9. Check final: el cartel ya no tiene que estar visible

await expect(page.getByText("Added!")).not.toBeVisible();

});

En la parte de añadir al poner el locator se repetia el elemento es por eso que toca darle click primero porq eu hay dos por esa barra qeu aparece al añadir al carro, pero bueno ya esta .

Comparto mi solución al reto...

import { test, expect } from '@playwright/test';

test.describe("navigation", () => {

test.beforeEach(async ({ page }) => {

// Go to the starting url before each test.

await page.goto("https://automationexercise.com/products");

await expect(page).toHaveURL("https://automationexercise.com/products");

});

test("main navigation", async ({ page }) => {

// Assertions use the expect API.

await expect(page.locator('.features_items .col-sm-4 .choose ul').first()).toBeVisible();

await page.locator('.features_items .col-sm-4 .choose ul').first().click();

await expect(page.url()).toContain('https://automationexercise.com/product\_details/1');

await expect(page.locator('#quantity')).toBeVisible();

await page.locator('#quantity').clear();

await page.locator('#quantity').fill('3');

await expect(page.locator('.cart')).toBeVisible;

await page.locator('.cart').click();

await expect(page.locator('.modal-content')).toBeVisible;

await expect(page.locator('.modal-title')).toContainText('Added!');

await expect(page.locator('.btn-block')).toBeVisible;

await page.locator('.btn-block').click();

await expect(page.locator('.modal-content')).not.toBeVisible();

});

});

Mis tests:

test('test', async ({ page }) => {

    await page.goto('https://automationexercise.com/products');

    await page.locator('a[href="/product_details/1"]').click();    

    await page.locator('#quantity').fill('3');

    await page.locator('button.cart').click();

    await expect(page.locator('#cartModal')).toBeVisible();

    await page.locator('.btn.btn-success.close-modal.btn-block').click();

    await expect(page.locator('#cartModal')).not.toBeVisible();

});

estuvo genial, yo resolvi asi y solucione lo de los anuncios con un test.before para bloquear los anuncios de terceros. import { test, expect } from '@playwright/test';

test.beforeEach(async ({ page }) => {

  // Bloquear anuncios de terceros

  await page.route('**/*', (route) => {

    const url = route.request().url();

    const ads = [

      'doubleclick.net',

      'googlesyndication.com',

      'googleadservices.com',

      'googletagmanager.com',

    ];

    if (ads.some(ad => url.includes(ad))) {

      return route.abort();

    }

 

    route.continue();

  });

  // Ir a la página base

  await page.goto('https://automationexercise.com/');

  // Cerrar banner de la app si aparece

  const banner = page.getByTestId('banner-close');

  if (await banner.count() > 0 && await banner.isVisible()) {

    await banner.click();

  }

});

test('@regression reto producto', async ({ page }) => {

  // 1. ir a navegador

  await page.goto('https://automationexercise.com/');

  // 2. desliza a un producto por el nombre (tiende a cambiar orden, mejor por algo especifico)

  await page  .locator('.product-image-wrapper', { hasText: 'Little Girls Mr. Panda Shirt' }).getByText('View Product').click();

  await expect(page).toHaveURL(/product_details/);

  // 3. ya en el detalle y verifica que este en el producto que es

  await expect(page.getByText('Little Girls Mr. Panda Shirt')).toBeVisible();

  await page.locator('#quantity').click();

  // 4. añade 3 productos

  await page.locator('#quantity').fill('3');

  await page.getByRole('button', { name: ' Add to cart' }).click();

  // 5. valida mesace de agregado

  await expect(page.getByText(' Added! Your product has')).toBeVisible();

  await page.getByRole('button', { name: 'Continue Shopping' }).click();

  // 6. valida que el modal ya no este o este oculto

   await expect(page.getByText(' Added! Your product has')).toBeHidden();

});

Listo reto completado, estuvo un poco complicado por todos los pop-up de anuncios, pero se aprendió a tratarlos en caso de que aparezcan.

import { test, expect } from "@playwright/test"; test("challenge 1", async ({ page }) => { //go to website await page.goto("https://automationexercise.com/category_products"); //validate products class .features_items is visible await expect(page.locator(".features_items")).toBeVisible(); //click on first product await page.locator("//li/a[text()='View Product']").first().click(); //go back to previous page await page.goBack(); //add 3 products to cart for (let i = 0; i < 3; i++) { await page .locator("//div[contains(@class, 'productinfo')]/a[text()='Add to cart']") .nth(i) .click(); await page.locator("//button[text()='Continue Shopping']").click(); } //validate modal is not v await expect(page.locator(".modal-content")).not.toBeVisible(); });
import { test, expect } from '@playwright/test'; test('test', async ({ page }) => { await page.goto('https://automationexercise.com/'); }); test('test-3', async ({ page }) => { await page.goto('https://automationexercise.com/'); await page.getByRole('link', { name: ' Products' }).click(); await page.getByRole('link', { name: ' Products' }).press('ArrowRight'); await page.getByRole('link', { name: ' Products' }).press('ArrowDown'); await page.getByRole('link', { name: ' Products' }).press('ArrowRight'); await page.getByRole('link', { name: ' Products' }).press('ArrowDown'); }); test('test-2', async ({ page }) => { await page.goto('https://automationexercise.com/'); await page.getByRole('link', { name: ' Products' }).click(); await page.getByRole('link', { name: ' Products' }).press('ArrowRight'); await page.getByRole('link', { name: ' Products' }).press('ArrowDown'); await page.getByRole('link', { name: ' View Product' }).first().click(); }); test('test-1', async ({ page }) => { await page.goto('https://automationexercise.com/'); await page.getByRole('link', { name: ' Products' }).click(); await page.getByRole('link', { name: ' Products' }).press('ArrowRight'); await page.getByRole('link', { name: ' Products' }).press('ArrowDown'); await page.getByRole('link', { name: ' View Product' }).first().click(); await page.locator('#quantity').fill('3'); await page.getByRole('button', { name: ' Add to cart' }).click(); await page.getByRole('button', { name: 'Continue Shopping' }).click(); }); test('test-0', async ({ page }) => { await page.goto('https://automationexercise.com/'); await page.getByRole('link', { name: ' Products' }).click(); await page.getByRole('link', { name: ' Products' }).press('ArrowRight'); await page.getByRole('link', { name: ' Products' }).press('ArrowDown'); await page.getByRole('link', { name: ' View Product' }).first().click(); await page.locator('#quantity').fill('3'); await page.getByRole('button', { name: ' Add to cart' }).click(); await page.getByRole('button', { name: 'Continue Shopping' }).click(); await expect(page.locator('text=Continue Shopping')).toBeHidden(); });