Here is a test for the order history page:
- Log in.
- Search for a product.
- Open the product page.
- Add it to the cart.
- Go to checkout.
- Fill in the address.
- Pay.
- Open order history.
- Check the new order is there.
Nine steps. The test is about step 9. The other eight are setup.
Each of those eight steps is a place the test can break for a reason that has nothing to do with order history. The search box moves. The payment sandbox is slow. A cookie banner covers the checkout button. The test goes red, somebody spends twenty minutes on it, and order history was fine the whole time.
Use the browser only for what users see
Your application already has a faster way to create an order: the API that the checkout page calls. A hybrid test uses it.
- API steps do the setup and the cleanup. They are fast, and they do not care where a button sits.
- UI steps test the screen you actually care about, the way a user sees it.
Both kinds of step live in the same test case, run in order, and share data.
How it works in QAEverest
Every step in a UI Automation test case has a UI / API switch.
A UI step is what you already write: a plain-English sentence like "click Sign in" or "the user should see Order confirmed".
An API step opens the same request editor used in API Automation: method, URL, headers, query and path parameters, a body (JSON, text or form), and authorization (Bearer token, Basic auth or API key). The step's sentence still does two jobs:
- It says what status you expect. "Then the API returns 201" or "Then the response status code should be 401". If you do not state one, any 2xx response passes.
- It saves a value from the response. "capture $.id as {{orderId}}" stores the id, and every later step in the test case can use {{orderId}}, UI steps included.
A worked example
Here is the order history test again, rewritten as a hybrid test:
| # | Kind | Step |
|---|---|---|
| 1 | UI | Log in as a customer |
| 2 | API | POST /api/orders. Then the API returns 201, capture $.id as {{orderId}} |
| 3 | UI | Open order history |
| 4 | UI | Search for "{{orderId}}" |
| 5 | UI | The user should see the order {{orderId}} with status Placed |
| 6 | API | DELETE /api/orders/{{orderId}}. Then the API returns 204 |
Six steps instead of nine, and every UI step is about order history.
Two details make this work.
The API call uses the browser's session. API steps run through the same browser context as the UI steps, so they share cookies. If step 1 logs in through the page, step 2 is already authenticated. If an API step sets a cookie, the page sees it too.
The test cleans up after itself. Step 6 deletes the order it created. The next run starts from the same place, and your test environment does not fill up with orders called "test test test".
When to use which
| Use an API step for | Use a UI step for |
|---|---|
| Creating test data: users, orders, products | Anything the user sees or clicks |
| Putting an account into a state: expired plan, locked user | Layout, text, messages and errors on screen |
| Cleaning up after the test | Flows where the screen itself is what you are testing |
| Checking that an endpoint rejects a request | Login, if login is the feature under test |
A simple rule: if a step is not what the test is about, and your app has an API for it, make it an API step.
Environments and data
- One test, many environments. An API step with a relative path like /api/orders uses the environment's API Base URL. If you have not set one, it uses the suite's Base URL. The same test runs against QA and staging without editing the steps.
- Environment variables work in API steps. Values you define for an environment can be used in URLs, headers and bodies. If a step captures a value with the same name, the captured value wins for the rest of that test case.
- Test data works too. Values from your test data library can go into the URL, headers and body, and data-driven runs repeat the whole hybrid test once per data row.
What the report shows
A UI step shows a screenshot. An API step shows the request and response instead:
- method and final URL, with query parameters
- status code, coloured green for 2xx and amber otherwise
- how long the call took
- the values it captured, or a warning if the path was not found
- the response body, which you can expand
Authorization and Cookie headers are removed before anything is stored, so your tokens do not end up in reports.
When step 5 fails, you can see straight away whether the order was ever created in step 2, or whether the problem is on the page.
Try it on one test
Pick your slowest UI test. Count the steps that are not about the thing being tested. If it is more than half, move that setup to API steps, run it a few times, and compare how often it fails.



