---
title: "ทดสอบ OTP อีเมลด้วย Playwright จากกล่องจดหมายเดิม"
description: "เชื่อม Playwright กับ Mailera เพื่ออ่าน OTP จากกล่องจดหมายทดสอบเดิม รอแบบมีเส้นตาย ตรวจรหัสให้ตรงรอบ และแก้ปัญหาเมื่ออีเมลไม่มา"
url: https://mailera.app/th/blog/playwright-email-otp
published: 2026-10-25
updated: 2026-10-25
---

# ทดสอบ OTP อีเมลด้วย Playwright จากกล่องจดหมายเดิม

ให้ Playwright ขอรหัส อ่านอีเมลผ่าน Mailera REST API แล้วตรวจผลหลังล็อกอิน โดยแยกการรออีเมลออกจากการตรวจว่ารหัสเป็นของรอบทดสอบนี้

## ต้องเตรียมอะไรบ้างก่อนเริ่ม?

การทดสอบ OTP อีเมลด้วย Playwright มีงานสองส่วน: ควบคุมหน้าเว็บ และอ่านอีเมลที่แอปส่งออกมา ให้แยกสองส่วนนี้ไว้คนละฟังก์ชัน เพื่อดูได้ว่าชุดทดสอบล้มเหลวที่หน้าเว็บ การรับอีเมล หรือการยืนยันรหัส

[Mailera เชื่อมกล่องจดหมายเดิมเข้ากับแอป](https://mailera.app/th/product) ผ่าน REST API จึงไม่ต้องเปลี่ยนที่อยู่อีเมลของบัญชีทดสอบ หากต้องการดูพื้นฐานก่อนเขียนชุดทดสอบ อ่าน[วิธีอ่าน OTP จากกล่องจดหมายของคุณ](https://mailera.app/th/blog/email-otp-api)

| สิ่งที่ต้องมี | การเตรียมที่แนะนำ |
| --- | --- |
| แอปและบัญชีทดสอบ | ใช้เฉพาะระบบที่คุณได้รับอนุญาตให้ทดสอบ |
| กล่องจดหมายของคุณ | แยกจากกล่องจดหมายส่วนตัวที่มีข้อมูลจริง |
| Playwright | ใช้โครงการทดสอบที่เปิดหน้าล็อกอินของแอปได้แล้ว |
| คีย์ API | จำกัดขอบเขตเฉพาะกลุ่มกล่องจดหมายทดสอบ และให้สิทธิ์ `read` |
| ข้อมูลสำหรับจับคู่รอบ | ถ้าแอปทดสอบทำได้ ให้ใส่ตัวระบุเฉพาะรอบในหัวข้ออีเมล; ถ้าทำไม่ได้ ให้รันทีละรอบต่อกล่องจดหมายแทน |
| ระบบเก็บความลับ | เก็บคีย์ในตัวแปรสภาพแวดล้อมหรือระบบจัดการความลับของ CI |

สำหรับ Outlook และ Microsoft 365 ใช้[การเชื่อม Microsoft ผ่าน OAuth](https://mailera.app/th/providers/microsoft) ไม่ใช่รหัสผ่านสำหรับแอป ส่วน[การเชื่อม Gmail](https://mailera.app/th/providers/gmail) ของ Mailera ใช้รหัสผ่านสำหรับแอป (app password) ซึ่ง Google กำหนดให้บัญชีเปิดการยืนยันสองขั้นตอน ตาม[ข้อกำหนดรหัสผ่านสำหรับแอปของ Google](https://support.google.com/accounts/answer/185833)

หากต้องแยกว่ารหัสผ่านประเภทนี้ต่างจากรหัสผ่านบัญชีอย่างไร อ่าน[รหัสผ่านสำหรับแอปของกล่องจดหมาย](https://mailera.app/th/blog/email-app-passwords) ก่อนตั้งค่าการเชื่อมต่อ

ใน Mailera เปิด **การตั้งค่า** ไปที่แท็บ **API key** แล้วเลือก **สร้าง API key** กำหนด **ขอบเขตกล่องจดหมาย** ให้เป็นกลุ่มทดสอบ และเลือกสิทธิ์ `read` คีย์ใหม่จะแสดงเพียงครั้งเดียว จึงควรบันทึกลงระบบจัดการความลับทันที ไม่ใส่ไว้ในไฟล์ที่ส่งเข้า Git

![การกำหนดคีย์ API ให้เข้าถึงเฉพาะกลุ่มกล่องจดหมายทดสอบด้วยสิทธิ์อ่าน](https://mailera.app/media/c73176b6bf9e1502/otp-playwright-api-key-scope-th-1200.jpg)
_ให้ตัวช่วยอ่าน OTP ใช้คีย์ที่จำกัดกลุ่มกล่องจดหมายและสิทธิ์_

## เขียนชุดทดสอบตั้งแต่ขอรหัสจนล็อกอินสำเร็จ

เริ่มจากรันทีละรอบต่อกล่องจดหมาย หากแอปทดสอบรองรับการกำหนดหัวข้อจากฝั่งเซิร์ฟเวอร์ ให้ใช้หัวข้ออีเมลที่ไม่ซ้ำกันในแต่ละรอบ เพราะการตั้งค่าฝั่ง Playwright อย่างเดียวไม่ได้ทำให้แอปส่งหัวข้อตามนั้น

ลำดับงานคือขอรหัส รอข้อความที่ตรงรอบ แล้วจึงกรอกรหัส อย่าถือว่าการอ่าน OTP ได้เท่ากับการล็อกอินสำเร็จ

![ลำดับการขอ OTP อ่านอีเมล ตรวจรอบ และยืนยันผลล็อกอิน พร้อมทางออกเมื่อรอเกินเวลา](https://mailera.app/media/53c617b1782545ea/otp-playwright-otp-test-flow-th-1200.jpg)
_รออีเมลและตรวจว่าตรงรอบก่อนกรอก แต่ตัดสินผลจากสถานะหลังล็อกอิน_

### 1. เลือกกล่องจดหมายให้ชัดเจน

ก่อนเรียกคำสั่งแรก ให้โหลดคีย์จากระบบจัดการความลับลงตัวแปรสภาพแวดล้อม `MAILERA_API_KEY` ของ shell หรือขั้นตอน CI ที่จะรันคำสั่ง โดยไม่พิมพ์ค่าคีย์ลง log

เรียก `GET /mailboxes` แล้วตรวจ `email`, `group_id` และ `id` ของรายการที่ต้องการ อย่าเลือก `data[0]` โดยอัตโนมัติ เพราะลำดับรายการไม่ใช่ตัวระบุบัญชีทดสอบ

```bash
curl --fail-with-body \
  'https://mailera.app/api/public/v1/mailboxes' \
  -H "Authorization: Bearer $MAILERA_API_KEY"
```

หากยังไม่พบกล่องจดหมาย ให้ตรวจหน้าถัดไปด้วย `limit` และ `offset` แล้วบันทึก `id` ที่เลือกลง `$MAILBOX_ID` ส่วนคีย์เก็บใน `$MAILERA_API_KEY` ผลลัพธ์คำสั่งนี้มีข้อมูลกล่องจดหมาย จึงไม่ควรส่งออกไปยังบันทึก CI ที่เปิดอ่านได้ทั่วไป

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

| ตัวแปรสภาพแวดล้อม | ค่าที่ต้องกำหนด |
| --- | --- |
| `MAILERA_API_KEY` | คีย์ที่มีสิทธิ์ `read` และเข้าถึงกลุ่มกล่องจดหมายทดสอบได้ |
| `MAILBOX_ID` | ค่า `id` ของกล่องจดหมายที่เลือกจากผลลัพธ์ด้านบน |
| `TEST_OTP_FROM` | ที่อยู่ผู้ส่งที่แอปใช้ส่ง OTP |
| `TEST_OTP_SUBJECT` | หัวข้อเต็มที่มีตัวระบุเฉพาะรอบ และตรงกับหัวข้อที่แอปจะส่ง |

หากรันใน shell ให้ส่งออกตัวแปรเหล่านี้ด้วย `export` หากรันใน CI ให้ส่งตัวแปรเข้าขั้นตอนที่เรียก API ด้วย ไม่ใช่ตั้งไว้เฉพาะขั้นตอนเตรียมงาน สำหรับ GitHub Actions ดู[วิธีส่ง secrets ให้ขั้นตอนรันผ่านตัวแปรสภาพแวดล้อม](https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets)

![รายการกล่องจดหมายทดสอบใน Mailera พร้อมสถานะและเวลาซิงก์ล่าสุด](https://mailera.app/media/5aacf379d5f25c32/otp-playwright-test-mailbox-th-1200.jpg)
_ตรวจกล่องเป้าหมายและเวลาซิงก์ก่อนเพิ่มเวลารอใน Playwright_

### 2. เลือกวิธีอ่านรหัสให้เหมาะกับการตรวจรอบ

`GET /mailboxes/{id}/otp` ใช้อ่าน OTP ล่าสุด โดยมีตัวกรอง `from`, `subject` และ `since_minutes` และต้องใช้สิทธิ์ `read`

```bash
curl --fail-with-body --get \
  "https://mailera.app/api/public/v1/mailboxes/$MAILBOX_ID/otp" \
  -H "Authorization: Bearer $MAILERA_API_KEY" \
  --data-urlencode "from=$TEST_OTP_FROM" \
  --data-urlencode "subject=$TEST_OTP_SUBJECT" \
  --data-urlencode 'since_minutes=5'
```

ตัวอย่างนี้ส่ง `since_minutes=5` พร้อม `from` และ `subject` ระวังผลลัพธ์คำสั่งนี้มีรหัสที่ต้องปกปิด

หากต้องการตรวจข้อมูลของข้อความก่อนใช้รหัส ให้ใช้ `GET /messages/search` พร้อม `mailbox`, `from`, `q` และ `extract=otp` แล้วอ่าน `otp.code` จากผลลัพธ์ พร้อมตรวจ `to`, `subject` และ `received_at` ของข้อความเดียวกันประกอบ ดูรายการปลายทาง API เพิ่มเติมใน[เอกสาร API ของ Mailera](https://mailera.app/th/docs)

### 3. แยกตัวช่วยอ่านอีเมลออกจากหน้าเว็บ

ให้ตัวช่วยอ่านอีเมลรับข้อมูลของรอบทดสอบจากส่วนควบคุมหน้าเว็บ ได้แก่ กล่องจดหมาย ผู้รับ ผู้ส่ง หัวข้อเฉพาะรอบ และเวลาเริ่มขอรหัส กำหนดเส้นตายรวมให้ตัวช่วยนี้ด้วย เพื่อไม่ให้ชุดทดสอบรออีเมลโดยไม่สิ้นสุด

ภายในตัวช่วย ให้เรียงการทำงานดังนี้:

1. ค้นหาข้อความด้วยกล่องจดหมายและผู้ส่งที่กำหนด พร้อมใช้หัวข้อเฉพาะรอบเป็นคำค้น
2. ตรวจ `mailbox_id`, `from.address`, ผู้รับใน `to`, `subject` และ `received_at` ของผลลัพธ์ก่อนอ่าน `otp.code` อย่าถือว่าการค้นเจอคำในหัวข้อเพียงอย่างเดียวเพียงพอ
3. หากมี `next_cursor` ให้ตรวจหน้าถัดไปหรือหยุดเพื่อปรับตัวกรอง อย่าเลือกข้อความแรกโดยละเลยผลลัพธ์ที่เหลือ
4. หากพบข้อความตรงเงื่อนไขมากกว่าหนึ่งฉบับ ให้หยุดด้วยข้อผิดพลาดที่ระบุว่าเลือกข้อความไม่ได้ แทนการเดารหัส
5. หากยังไม่พบ ให้พักก่อนตรวจซ้ำ และหยุดเมื่อครบเส้นตาย

การตรวจ `received_at` เป็นเงื่อนไขเสริม ไม่ใช่หลักฐานเดียวว่าข้อความเป็นของรอบนี้ จุดที่ใช้จับคู่รอบคือหัวข้อเฉพาะรอบซึ่งแอปของคุณสร้างหรือรับค่าจากการตั้งค่าทดสอบ

วงรอควรทำซ้ำเมื่อยังไม่พบข้อความที่ตรงเงื่อนไข แต่ไม่ควรกลืนข้อผิดพลาด HTTP แล้วลองใหม่ทุกชนิด กรณีคีย์ผิดหรือไม่มีสิทธิ์ควรหยุดเพื่อแก้การตั้งค่า ไม่ใช่ใช้เวลารอทั้งหมดกับคำขอเดิม

### 4. ขอรหัส กรอกกลับ และตรวจสถานะหลังล็อกอิน

ในส่วนควบคุมหน้าเว็บของ Playwright ให้ใช้ชื่อช่องและปุ่มที่ตรงกับแอปทดสอบของคุณ แล้วเรียงขั้นตอนดังนี้:

1. เปิดหน้าล็อกอินและกรอกที่อยู่อีเมลของบัญชีทดสอบที่ตรงกับกล่องจดหมายที่เลือกไว้
2. บันทึกเวลาเริ่มต้นก่อนกดขอรหัส แล้วส่งเวลาและข้อมูลประจำรอบให้ตัวช่วยอ่านอีเมล
3. รอรหัสจากข้อความที่ผ่านเงื่อนไข หากตัวช่วยหมดเวลาหรือเลือกข้อความไม่ได้ ให้จบรอบด้วยข้อผิดพลาด ไม่กดขอรหัสใหม่เองในวงรอ
4. กรอกรหัสและกดยืนยัน จากนั้นตรวจองค์ประกอบที่แอปแสดงเฉพาะเมื่อเข้าสู่ระบบแล้ว

หากหน้าเว็บแสดงบัญชีที่เข้าใช้ ให้ตรวจด้วยว่าเป็นบัญชีทดสอบที่ต้องการ อย่าจบการทดสอบทันทีหลังกรอกรหัส

เก็บคีย์ API ไว้ในกระบวนการรันชุดทดสอบ ไม่ส่งเข้า JavaScript ของหน้าเว็บ โครงสร้างการเชื่อมต่อแบบนี้อธิบายเพิ่มเติมไว้ใน[หน้าสำหรับนักพัฒนา](https://mailera.app/th/developers)

## จะรอรหัสโดยไม่หยิบ OTP เก่าหรือรหัสของงานอื่นได้อย่างไร?

ปลายทาง API สำหรับอ่าน OTP รองรับ `from`, `subject` และ `since_minutes` แต่ชุดทดสอบควรตรวจข้อความกับตัวระบุเฉพาะรอบก่อนใช้รหัส อย่าเลือก OTP เพียงเพราะเป็นรหัสล่าสุด

ให้แยกการตรวจเป็นสองเรื่องหลัก:

- **กล่องและผู้รับถูกต้อง:** ระบุ `$MAILBOX_ID` และตรวจผู้รับของข้อความ อย่าอาศัยเพียงที่อยู่ผู้ส่ง
- **ข้อความตรงรอบ:** ใช้ตัวระบุเฉพาะรอบในหัวข้อหรือเนื้อหาเมื่อแอปรองรับ พร้อมตรวจเวลาเป็นเงื่อนไขเสริม
- **รหัสยังใช้ได้:** ให้แอปเป็นผู้ตัดสิน แล้วตรวจผลหลังยืนยันรหัส การเลือกอีเมลถูกฉบับไม่ได้แปลว่าแอปจะยอมรับรหัสนั้น

หากแอปใส่ตัวระบุไว้ในเนื้อหา ใช้ `GET /mailboxes/{id}/messages` เพื่อค้นหารายการ แล้วอ่าน `GET /mailboxes/{id}/messages/{msgId}` ตรวจ `body.text` หรือ `body.html` ก่อนเลือก OTP รายการข้อความมีตัวกรอง `from` และ `since` รวมถึง `cursor` สำหรับหน้าถัดไป

สำหรับแอปที่ไม่มีตัวระบุเฉพาะรอบ ให้รันทีละรอบต่อกล่องจดหมาย และอย่ามีงานอื่นขอ OTP ให้บัญชีเดียวกันระหว่างนั้น หากแยกไม่ได้ว่าข้อความเป็นของรอบใด ให้หยุดด้วยผลที่ระบุว่าเลือกข้อความไม่ได้ แทนการเดารหัสล่าสุด

เมื่อรันหลาย worker ให้แยกบัญชีและกล่องจดหมายของแต่ละ worker อย่าให้ทุกงานใช้ `$MAILBOX_ID` เดียวกันแล้วแข่งกันอ่านรหัส

## ข้อผิดพลาดที่พบบ่อยและวิธีตรวจสอบ

เริ่มจากดูว่าอีเมลมาถึงหรือไม่ ก่อนเพิ่มเวลารอ หากข้อความยังไม่ถูกซิงก์ การเปลี่ยนตัวเลือกช่องกรอก OTP ใน Playwright จะไม่ช่วยแก้ปัญหา

| อาการ | จุดที่ควรสงสัย | ขั้นตอนตรวจสอบ |
| --- | --- | --- |
| ไม่พบ OTP | ผู้ส่ง หัวข้อ หรือกล่องจดหมายไม่ตรง | ตรวจค่าตัวแปรและข้อความจริง โดยปิดบังรหัส |
| พบรหัสแต่แอปปฏิเสธ | เลือกข้อความผิดรอบ หรือรหัสไม่ผ่านกติกาของแอป | ตรวจตัวระบุรอบและประวัติการขอรหัสใหม่ |
| รอจนหมดเวลา | การส่งอีเมล การเชื่อมต่อ หรือการซิงก์ | ตรวจ `/status` และเวลาซิงก์ล่าสุด ก่อนขยายเส้นตาย |
| อ่านผิดกล่อง | เลือกรายการแรกหรือแชร์ค่าระหว่าง worker | เทียบ `id`, `email`, `group_id` กับบัญชีทดสอบ |
| คีย์ใช้เรียกไม่ได้ | สิทธิ์หรือขอบเขตกล่องจดหมายไม่ตรง | ตรวจ `read` กลุ่มที่คีย์เข้าถึงได้ และการเพิกถอนคีย์ |
| ค้นพบหลายข้อความ | ใช้หัวข้อซ้ำหรือมีการขอรหัสซ้ำ | หยุดรอบนั้น แล้วเตรียมตัวระบุใหม่ |

`GET /mailboxes/{id}/status` ตรวจการลงชื่อเข้าใช้ Microsoft โดยตรง ส่วนผู้ให้บริการอื่นใช้สถานะจากการซิงก์ล่าสุด จึงควรดู `last_sync_at` ประกอบ ไม่ตีความทุกสถานะว่าเป็นการลงชื่อเข้าใช้ใหม่ในขณะนั้น

หากต้องสั่งซิงก์เอง `POST /mailboxes/{id}/sync` ต้องมีสิทธิ์ `sync` เพิ่มจาก `read` และใช้ปลุกกล่องจดหมายที่อยู่ในโหมดพักได้ ไม่จำเป็นต้องเพิ่มสิทธิ์นี้ให้คีย์อ่าน OTP ทุกคีย์

กรณีไม่พบข้อความในกล่องจดหมายเข้า ตรวจ `GET /mailboxes/{id}/placement` โดยใช้ `from`, `subject` และ `since_minutes` หรือเปิดโฟลเดอร์อีเมลขยะของ Outlook และสแปมของ Gmail หากพบอีเมลในโฟลเดอร์เหล่านี้ ใช้ปุ่ม **ไม่ใช่อีเมลขยะ** ในหน้าอ่านอีเมลของ Mailera เพื่อย้ายออกมา แต่แยกขั้นตอนนี้ออกจากชุดทดสอบล็อกอินอัตโนมัติ ไม่ควรย้ายจดหมายอัตโนมัติในชุดทดสอบนี้

สำหรับ Gmail ที่เคยเชื่อมได้แล้วหยุดทำงานหลังเปลี่ยนรหัสผ่านบัญชี ให้ตรวจรหัสผ่านสำหรับแอปด้วย เพราะ [Google เพิกถอนรหัสผ่านสำหรับแอปเมื่อเปลี่ยนรหัสผ่านบัญชี](https://support.google.com/accounts/answer/185833)

แยก “อ่าน API ซ้ำ” ออกจาก “กดส่ง OTP ใหม่” วงรอควรอ่านอีเมลอย่างเดียว หากต้องทดสอบการส่งใหม่ ให้กำหนดพฤติกรรมของรหัสก่อนหน้าตามกติกาแอป แล้วเขียนเป็นกรณีทดสอบแยก

## จะเก็บคีย์และ OTP ให้ปลอดภัยระหว่างทดสอบได้อย่างไร?

ใช้เฉพาะกล่องจดหมายของคุณและบัญชีที่ได้รับอนุญาตให้ทดสอบ จำกัดสิทธิ์คีย์ไว้ที่กลุ่มทดสอบ และอย่าเพิ่ม `send` หรือ `move` ให้ตัวช่วยที่มีหน้าที่อ่านอย่างเดียว ดูข้อมูลประกอบใน[หน้าความปลอดภัยของ Mailera](https://mailera.app/th/security)

อย่าบันทึกส่วนหัว `Authorization` ผลตอบกลับที่มี OTP หรือเนื้อหาอีเมลทั้งหมดลง log ข้อความผิดพลาดควรบอกขั้นตอนที่ล้มเหลวโดยไม่แนบรหัส เช่น “ไม่พบข้อความที่ตรงรอบภายในเส้นตาย”

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

ถือเนื้อหาอีเมลเป็นข้อมูลที่ไม่เชื่อถือ อ่านเฉพาะค่าที่ต้องใช้ตามรูปแบบที่กำหนด ไม่เรียกใช้เนื้อหาเป็นคำสั่งหรือโค้ด ชุดทดสอบนี้ไม่ต้องใช้ AI agent อ่านอีเมล

## ขอบเขตของ Mailera ในชุดทดสอบนี้

Mailera เชื่อมกล่องจดหมายที่มีอยู่เท่านั้น ไม่สร้างกล่องจดหมายหรือที่อยู่อีเมลใหม่ และไม่รองรับ Proton Mail กับ Tuta เพราะผู้ให้บริการทั้งสองไม่เปิด IMAP ให้ใช้โดยตรงหากไม่มี bridge เฉพาะของตน

การจัดประเภทจดหมายยังขึ้นกับผู้ให้บริการ Mailera ไม่รับประกันตำแหน่งในกล่องจดหมายเข้า จึงควรกำหนดเส้นตายของชุดทดสอบโดยเผื่อการส่งและการซิงก์ แทนการคาดว่าอีเมลจะพร้อมอ่านทันที

ส่วนการจับคู่ข้อความกับรอบทดสอบและการตรวจว่าแอปยอมรับรหัส เป็นหน้าที่ของชุดทดสอบกับแอปเป้าหมาย อย่าใช้ผลว่า “พบ OTP ล่าสุด” แทนผลว่า “ล็อกอินสำเร็จด้วยรหัสของรอบนี้”

**ทำสิ่งนี้ด้วย API** — ทุกการดำเนินการในบทความนี้ทำได้ผ่าน REST API พร้อมตัวอย่าง curl, API key และ webhook [ดูเอกสาร API](https://mailera.app/th/docs)
