# Test sign-in and texting with real SMS.

> Test everything your app texts end to end, from sign-in codes and invite links to confirmations and two-way replies, with real US phone numbers, including real SIM lines, in Playwright, Cypress and CI.

A mocked code proves your form works. A real number proves the text arrives. Give each test its own line, read the code in one call, and run it on every push.

## Pick your stack.

Working guides for the test runners and sign-in providers you already use.

- [Playwright](https://www.phonekit.io/docs/guides/playwright): A complete Playwright SMS test: receive a fresh code with the Phonekit SDK, submit it in the browser, and assert the signed-in account.
- [Continuous integration](https://www.phonekit.io/docs/guides/ci): A complete GitHub Actions workflow for SDK-based SMS verification tests, with scoped secrets, number serialization, and trusted deployment configuration.
- [Cypress](https://www.phonekit.io/docs/guides/cypress): A Cypress SMS recipe with server-side Phonekit tasks, an explicit fresh-message cursor, hidden code entry, and a final application assertion.
- [Supabase Auth](https://www.phonekit.io/docs/guides/supabase): Test Supabase SMS sign-in end to end with a selected Phonekit number, real receipt, verifyOtp, a session assertion, and explicit test-mode boundaries.
- [Firebase Auth](https://www.phonekit.io/docs/guides/firebase): A Firebase phone-auth acceptance recipe that preserves real app verification, receives an SMS through Phonekit, and distinguishes fictional-number coverage.
- [Twilio Verify](https://www.phonekit.io/docs/guides/twilio-verify): Run a complete Twilio Verify send, Phonekit SMS receipt and Verification Check test, with service isolation and unfinished-attempt cleanup.
- [iOS simulator / XCUITest](https://www.phonekit.io/docs/guides/ios-simulator): A native Swift XCUITest recipe that receives real SMS through a test-runner HTTP fixture and enters the fresh code into the iOS simulator.

## Three lines in your test.

Mark the number, trigger the text, then wait for the code. Only a text that arrives after the mark counts, so a stale code never passes a test and parallel runs never read each other's codes.

[Why each test gets its own number](https://www.phonekit.io/learn/one-number-per-test)

## Test anything your app texts.

Codes are where most teams start. Every wait returns the whole message, so the same test checks whatever your product sends.

- **Sign-in codes**: Sign-up, sign-in, phone change and two-step checks, with the code pulled out for you.
- **Invites and magic links**: Wait for the link, check where it goes, and open it in the browser your test controls.
- **Confirmations and alerts**: Bookings, orders, reminders and alerts. Assert on the text your product actually sent.
- **Conversations**: Text your product from your own numbers and check each reply, turn by turn.

## Products that text, tested end to end.

If your product lives in the text channel, a code isn't enough. Give a test agent its own number, text your product and check the reply. Your numbers can text each other, so you can test a whole conversation.

## Proven on every push.

Give CI a read-only key for its own numbers and one number per worker. A broken text path fails the build, not your users.

[Run it in GitHub Actions](https://www.phonekit.io/docs/guides/ci)

## The details.

- **Numbers**: US numbers. Standard is local VoIP; Mobile is a real SIM line, for flows that only text mobiles. [VoIP or real SIM](https://www.phonekit.io/learn/voip-vs-real-sim)
- **Messages**: The whole text of every message, with codes and links pulled out. Wait by sender, content or link. [SDK](https://www.phonekit.io/docs/sdk)
- **Freshness**: Mark the number before the text is sent. Only a later text counts. [One number per test](https://www.phonekit.io/learn/one-number-per-test)
- **Waiting**: The SDK checks every second until the deadline you set, up to an hour. [SDK](https://www.phonekit.io/docs/sdk)
- **Languages**: JS/TS SDK for Node test runners, an HTTP API for any language, and a CLI for any shell. [API](https://www.phonekit.io/docs/api)
- **CI**: A read-only key limited to its own numbers, with one number per worker. [CI guide](https://www.phonekit.io/docs/guides/ci)
- **Sending**: Tests text inside a closed loop, with per-number limits. [Limits](https://www.phonekit.io/docs/api#sending)
- **Price**: From $29 a month for four numbers. Extra Standard numbers are $5 a month. [Pricing](https://www.phonekit.io/pricing)

## Questions

### Can it read any text, not just codes?

Yes. Every wait returns the whole message: sender, body and time. Codes and links are pulled out for convenience, and you can wait for a message from a given sender, containing given text or linking to a given site.

### Do I still need real SMS if I mock the code?

Keep the mocks for speed. Add one real journey for each way users sign in, so a broken text path fails a test instead of reaching users.

### Which test frameworks and languages work?

The JS/TS SDK fits Playwright, Cypress and other Node test runners. The HTTP API works from any language, and the CLI works from any shell or CI step.

### How long does a code take to arrive?

As long as the service that sends it takes. Phonekit hands the code over as soon as the text lands, and your test fails clearly at the deadline you set if nothing arrives.

### Can tests run in parallel?

Yes. Give each worker its own number. Each test marks its number before the text is sent, so it never reads another run's code.

### Does Phonekit replace my SMS provider?

No. Your app keeps sending through its own provider. Phonekit is the number that receives the text, and can text back within its limits.

### Can I test a product that texts its users?

Yes. Give a test its own number, text your product and assert on the reply. Your numbers can text each other to test a whole conversation.

---

Source: https://www.phonekit.io/testing
