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
Tomar examen

Testing de Funcionalidades en Tiendas en Línea

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 3 años
      Mauro Mascheroni

      Mauro Mascheroni

      Estudiante
      Hace 3 años
      Douglas Lovera

      Douglas Lovera

      Estudiante
      Hace 3 años
      Ivan Martinez Calcaño

      Ivan Martinez Calcaño

      Estudiante
      Hace 3 meses
      •
      editado
        Elihu Garcia

        Elihu Garcia

        Estudiante
        Hace 2 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 3 años
      Michell gonzalez

      Michell gonzalez

      Estudiante
      Hace 14 días
      Miguel Stiven Herrera Gomez

      Miguel Stiven Herrera Gomez

      Estudiante
      Hace un mes
      •
      editado
      Ismael Ávila Ojeda

      Ismael Ávila Ojeda

      Estudiante
      Hace 3 meses
      •
      editado
      Diego Padovani

      Diego Padovani

      Estudiante
      Hace 3 meses
      Lennys Cantero

      Lennys Cantero

      Estudiante
      Hace 3 meses
      Cynthia Sotelo

      Cynthia Sotelo

      Estudiante
      Hace 3 meses
      YEIMY ROCIO FUQUEN AVILA

      YEIMY ROCIO FUQUEN AVILA

      Estudiante
      Hace 4 meses
      Darlinson Felipe Polania Camacho

      Darlinson Felipe Polania Camacho

      Estudiante
      Hace 4 meses
      Leonardo Buezo

      Leonardo Buezo

      Estudiante
      Hace 4 meses
      Felipe Madrigal

      Felipe Madrigal

      Estudiante
      Hace 5 meses
      fabian marentes

      fabian marentes

      Estudiante
      Hace 5 meses
      Juan Aguilera

      Juan Aguilera

      Estudiante
      Hace 6 meses
      Camilo Jiménez

      Camilo Jiménez

      Estudiante
      Hace 6 meses
      •
      editado
      Luis Antonio Del Rio Salguero

      Luis Antonio Del Rio Salguero

      Estudiante
      Hace 6 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(); });