tick()

ใน Cypress, cy.tick() ใช้สำหรับควบคุมเวลาในการทดสอบ. การใช้ cy.tick() จะเป็นประโยชน์ในการทดสอบที่มีตัวจับเวลา (timer) เช่น setTimeout หรือ setInterval และการทำงานที่เกี่ยวกับเวลาในแอปพลิเคชันของคุณ

ตัวอย่างการใช้ cy.tick():

// cypress/integration/tick_spec.js

describe('Testing timers with cy.tick()', () => {
  it('should handle setTimeout', () => {
    cy.visit('/your-page'); // Replace with the actual page you want to visit

    cy.window().then((win) => {
      // ใช้ฟังก์ชั่น setTimeout
      win.setTimeout(() => {
        console.log('setTimeout completed');
      }, 1000);

      // ใช้ cy.tick() เพื่อเลื่อนเวลาออกไป 1,000 มิลลิวินาที
      cy.tick(1000);

      // Assertions หลังจากมีการเรียกใช้ setTimeout
      cy.get('.result').should('have.text', 'setTimeout completed');
    });
  });

  it('should handle setInterval', () => {
    cy.visit('/your-page'); // Replace with the actual page you want to visit

    cy.window().then((win) => {
      // ใช้ฟังก์ชั่น setInterval
      const intervalId = win.setInterval(() => {
        console.log('setInterval tick');
      }, 500);

      // ใช้ cy.tick() เพื่อเลื่อนเวลาออกไป 1,500 มิลลิวินาที
      cy.tick(1500);

      // Assertions หลังจากมีการเรียกใช้ setInterval
      cy.get('.result').should('have.text', 'setInterval tick');

      // Clear the setInterval
      win.clearInterval(intervalId);
    });
  });
});

ในตัวอย่างนี้:

  • ใน should handle setTimeout, เราใช้ cy.tick(1000) เพื่อข้ามเวลาไป 1000 มิลลิวินาที เพื่อทำให้ setTimeout เสร็จสิ้น
  • ใน should handle setInterval, เราใช้ cy.tick(1500) เพื่อข้ามเวลาไป 1500 มิลลิวินาที เพื่อทำให้ setInterval ทำงานสามครั้ง

แม้ว่า cy.tick() จะทำงานได้ดีในการทดสอบ timers บางอย่าง แต่มีบางแง่ที่ควรพิจารณา ได้แก่:

  1. ไม่ได้ทำงานกับ requestAnimationFrame: cy.tick() ไม่สามารถทำงานกับ requestAnimationFrame ได้ แต่ Cypress มีคำสั่งอื่น ๆ เช่น cy.clock() ที่ช่วยในการทดสอบกับ requestAnimationFrame ได้ดี
  2. ต้องใช้กับคำสั่งที่ใช้เวลา: cy.tick() มีประโยชน์มากที่สุดเมื่อใช้กับคำสั่งที่เกี่ยวข้องกับเวลา เช่น setTimeout หรือ setInterval สำหรับการทดสอบการทำงานที่เกี่ยวข้องกับเวลาในแอปพลิเคชันของคุณ, ควรตรวจสอบว่ามีคำสั่งไหนที่เกี่ยวข้องกับเวลาบ้างและอาจจะต้องใช้ cy.tick() ในการทดสอบ

wait()

ใน Cypress ใช้สำหรับรอให้เหตุการณ์หรือเงื่อนไขบางอย่างเป็นจริงก่อนที่จะดำเนินการต่อ ฟังก์ชันนี้มีหลายวิธีในการใช้ และมักถูกใช้เพื่อรอคอยการทำงานที่เกี่ยวข้องกับการโต้ตอบกับ server, การทำงานที่เกี่ยวข้องกับ DOM elements ที่มีการ render หรือ update, หรือเหตุการณ์อื่น ๆ ที่ต้องการรอ

นี้คือหลายๆ รูปแบบที่ cy.wait() สามารถใช้ได้:

cy.get('#your-element').click();
cy.wait(1000); // รอ 1 วินาที
cy.get('.result').should('have.text', 'Expected Result');

รอให้ request จาก server ที่ถูกเรียกใช้ได้ (แบบไม่ใช้ wait())

cy.intercept('GET', '/api/data').as('getData');
cy.get('#fetch-data-button').click();
cy.wait('@getData').then((xhr) => {
  // ทำงานต่อหลังจากรอให้ request ทำงานเสร็จสมบูรณ์
  cy.get('.result').should('have.text', 'Data fetched successfully');
});

รอให้เหตุการณ์ใน DOM เปลี่ยนแปลง

cy.get('#your-element').click();
cy.wait(() => {
  // รอให้เงื่อนไขในฟังก์ชันเป็นจริง
  return Cypress.$('.result').text() === 'Expected Result';
});

cy.wait() มีหลายวิธีที่สามารถใช้กับเหตุการณ์หรือเงื่อนไขที่คุณต้องการรอคอย การใช้คำสั่งนี้ ขึ้นอยู่กับการออกแบบทดสอบว่าต้องการทดสอบอะไรบ้างในเว็บไซต์ของคุณ


ความแตกต่างระหว่าง tick() กับ wait()

เราพอจะสรุปความแตกต่างของฟังก์ชัน cy.tick() และ cy.wait() ใน Cypress ได้แล้ว เพราะมันมีวิธีการใช้งานที่แตกต่างกันอย่างชัดเจน:

cy.tick():

    • ใช้สำหรับควบคุมเวลาในการทดสอบ (time manipulation)
    • ทำให้เวลาข้ามไปข้ามมิลลิวินาทีตามที่ระบุ
    • มักถูกใช้ในการทดสอบ timers เช่น setTimeout, setInterval, หรือ requestAnimationFrame

cy.wait():

    • ใช้สำหรับรอให้เหตุการณ์หรือเงื่อนไขบางอย่างเป็นจริงก่อนที่จะดำเนินการต่อ
    • ไม่ได้ทำควบคุมเวลา แต่เป็นการรอ
    • มักถูกใช้ในการรอ response จาก server, การทำงานที่เกี่ยวข้องกับ DOM elements ที่มีการ render หรือ update, หรือเหตุการณ์อื่น ๆ ที่ต้องการรอ

ทั้งนี้สามารถเข้าไปดูวิธีการใช้งานเพิ่มเติมใน Documents ของ Cypress ต่อ ได้เลย


References