Scarnox · Blog

การรักษา CI ให้ผ่านเมื่อแอปของคุณมี captcha

ฟอร์มสมัครสมาชิกของคุณมี PopularCaptcha ชุดทดสอบ end-to-end ของคุณต้องสมัครสมาชิก ตอนนี้ CI แดงแล้ว และวิธีแก้ที่น่าดึงดูดคือปิด captcha ในบิลด์สำหรับทดสอบ แต่นั่นหมายความว่าโฟลว์ที่คุณทดสอบไม่ใช่โฟลว์ที่ผู้ใช้จริงได้รับ

มีหลายทางให้ออกจากปัญหานี้ แต่ละทางแตกต่างกันในความสมจริงของโฟลว์ที่ทดสอบ ดังนั้นเลือกทางที่ตรงกับคำถามที่การทดสอบของคุณต้องตอบ ตัวเลือกเรียงจากถูกที่สุดไปจนถึงสมจริงที่สุดโดยประมาณ

Scarnox แก้ PopularCaptcha ได้ในวันนี้ ประเภท captcha อื่น ๆ เร็ว ๆ นี้ ดังนั้นตัวเลือกการแก้ด้านล่างใช้ได้กับ PopularCaptcha เท่านั้น

1. test key สำหรับ unit test และการทดสอบในเครื่อง

ผู้ให้บริการ captcha หลายรายเผยแพร่ test key ที่ผ่านเสมอ ใช้เมื่อคุณควบคุมสภาพแวดล้อมและต้องการแค่ให้ฟอร์มแสดงผลและส่งได้ test key ไม่ได้ทดสอบการยืนยันจริง และไม่ช่วยเมื่อคุณทดสอบสภาพแวดล้อมที่ deploy แล้วซึ่งใช้ key จริง

2. bypass สำหรับ staging ของคุณเอง

บางทีมเพิ่ม secret header ที่ backend ยอมรับแทน token ของ captcha วิธีนี้เร็วและไม่มีค่าใช้จ่าย แต่เป็นเส้นทางโค้ดที่มีไว้สำหรับการทดสอบเท่านั้น และอาจกลายเป็นของ production ได้ด้วยการตั้งค่าผิดเพียงครั้งเดียว หากคุณใช้วิธีนี้ ให้ควบคุมด้วยการตรวจสอบสภาพแวดล้อม ทำให้ secret ยาวและสุ่ม และทดสอบว่ามันถูกปฏิเสธใน production

3. mock การเรียกยืนยัน

stub คำขอยืนยันฝั่งเซิร์ฟเวอร์ในการทดสอบ integration วิธีนี้ดีสำหรับตรวจสอบ logic ของ backend เช่น สิ่งที่เกิดขึ้นเมื่อการยืนยันล้มเหลว แต่ไม่บอกคุณว่าฝั่ง front end ส่ง token ถูกต้องหรือไม่ ดังนั้นควรจับคู่กับตัวเลือกอื่นอย่างใดอย่างหนึ่ง

4. แก้จริงใน staging และ smoke test

เมื่อคุณต้องการพิสูจน์ว่าโฟลว์จริงทำงานได้ตั้งแต่ต้นจนจบ ด้วย key จริง widget จริง และการยืนยันจริง ให้ดึง token จาก solving API ภายในการทดสอบ นี่คือตัวเลือกเดียวที่จับได้ว่าการเชื่อมต่อ widget เสียหายหรือไม่

ตัวช่วย Playwright มีลักษณะดังนี้

// ตัวช่วยสำหรับเทส Playwright
export async function solveCaptcha(page) {
  const sitekey = await page.getAttribute("[data-sitekey]", "data-sitekey");
  const r = await fetch("https://api.scarnox.com/api/tasks/create", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.SCARNOX_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      captcha_type: "PopularCaptchaTaskProxyless",
      site_key: sitekey,
      site_url: page.url(),
    }),
  });
  const { errorId, solution, errorCode, errorDescription } = await r.json();
  if (errorId !== 0) throw new Error(`${errorCode}: ${errorDescription}`);

  await page.evaluate((t) => {
    document.querySelectorAll('[name="h-captcha-response"],[name="g-recaptcha-response"]')
      .forEach((el) => { el.value = t; });
  }, solution.token);
}

เรียกใช้ทันทีก่อนที่การทดสอบจะ submit ฟอร์ม ไม่ใช่ตอนเริ่มการทดสอบ token หมดอายุภายในประมาณสองนาที และขั้นตอนช้า ๆ ก่อนหน้าในการทดสอบอาจใช้เวลาหมดช่วงนั้นไป

จำกัดการแก้ให้น้อยที่สุด

ชุดทดสอบที่สมัครสมาชิกทุกครั้งที่รันอาจทำการแก้จำนวนมากในหนึ่งสัปดาห์ ควรลดจำนวนลง

สำหรับกฎการลองซ้ำภายในตัวช่วย ให้ใช้นโยบายจาก การจัดการข้อผิดพลาดและ backoff

เก็บ key ไว้นอก repo

เก็บ key เป็น secret ของ CI ตั้งชื่อเช่น SCARNOX_KEY และอย่าใส่ไว้ในโค้ดทดสอบหรือ fixture หากรั่วไหล ให้สร้างใหม่จาก dashboard key เก่าจะหยุดทำงานทันที ดังนั้น key ที่รั่วไม่สามารถใช้รันการแก้ได้นาน

ใช้ key แยกสำหรับ CI หาก pipeline หนึ่งทำงานผิดปกติ คุณสามารถหมุนเวียน key ของ pipeline นั้นได้โดยไม่ต้องแตะสิ่งอื่น

ลองใช้บน staging ของคุณเอง

สร้างบัญชี และเริ่มด้วยเครดิตทดลองใช้ฟรี ไม่ต้องใช้บัตร ต่อตัวช่วยเข้ากับ smoke test หนึ่งตัวก่อน ยืนยันว่าการสมัครสมาชิกผ่านอย่างสะอาด แล้วจึงเพิ่มเข้าไปในชุดทดสอบที่เหลือ สำหรับค่าใช้จ่ายการแก้ในปริมาณมาก ดูราคาปัจจุบัน

สิ่งที่ควรยืนยันหลัง submit

การแก้ captcha สำเร็จพิสูจน์เพียงว่าขั้นตอน widget ทำงาน หลัง submit ให้ยืนยันสิ่งที่สำคัญต่อผู้ใช้ ได้แก่ หน้าถัดไปโหลด ข้อความสำเร็จปรากฏ และบัญชีหรือออร์เดอร์มีอยู่จริงในฐานข้อมูลของคุณ การทดสอบที่หยุดเพียงที่ "ฟอร์มไม่มี error" อาจผ่านได้ทั้งที่การสมัครสมาชิกล้มเหลวอย่างเงียบ ๆ ที่ backend

ให้การยืนยันอยู่ใกล้กับผลลัพธ์ทางธุรกิจ ตรวจสอบ URL ข้อความที่มองเห็น และหนึ่งเรคคอร์ดที่การทดสอบสร้างขึ้น ลบเรคคอร์ดนั้นเมื่อการรันจบ เพื่อให้การรันถัดไปเริ่มจากสถานะที่รู้แน่

รันการทดสอบ smoke ตามตารางเวลา

รันการทดสอบ smoke ที่แก้จริงตามตารางเวลา เช่นวันละครั้งกับ staging แทนการรันทุก pull request การรันตามตารางเวลาจะจับการเปลี่ยนแปลงที่เว็บทำข้ามคืน เช่น widget เวอร์ชันใหม่หรือ sitekey ที่ย้ายที่ โดยไม่ต้องใช้การแก้ในทุก commit แจ้งทีมเมื่อการรันตามตารางล้มเหลว และคงชุดทดสอบต่อ commit ไว้กับตัวเลือกที่เร็วกว่า

ขั้นตอนถัดไป