Skip to main content

UI and API contract replay

Use contract replay when a journey crosses the browser and backend and you want repeatable evidence without hand-writing every mock. SHAFT records matching browser traffic and SHAFT.API calls into a deterministic JSON contract, masks sensitive fields, and can later replay or validate the same exchanges.

Contract mode is opt-in. Existing browser interception, API calls, and reporting behave the same until a test starts recording, replay, assert, or verify mode.

Prerequisites​

  • A working web test (SHAFT.GUI.WebDriver) or API test (SHAFT.API) for the journey you want to keep.
  • A writable fixtures path for the contract JSON, for example src/test/resources/contracts/.
  • Agreement that the target environment allows its traffic to be kept as test evidence. See Redaction and normalization.

Record a contract​

Start recording before the browser navigation or API calls that should be kept. Use URL filters to avoid analytics, static assets, or unrelated backend calls.

RecordCheckoutContract.java
import com.shaft.driver.SHAFT;
import org.testng.annotations.Test;

public class CheckoutContractTest {
@Test
public void recordCheckoutContract() {
SHAFT.GUI.WebDriver driver = new SHAFT.GUI.WebDriver();
SHAFT.API api = new SHAFT.API("https://shop.example.test");

driver.browser().startContractRecording(
"src/test/resources/contracts/checkout.json",
"/api/");

driver.browser().navigateToURL("https://shop.example.test/checkout");
api.get("/api/cart");

SHAFT.Contracts.stopRecording();
driver.quit();
}
}

For API-only flows, use the facade directly:

RecordApiContract.java
SHAFT.Contracts.startRecording(
"src/test/resources/contracts/catalog.json",
"/api/catalog");

new SHAFT.API("https://shop.example.test")
.get("/api/catalog");

SHAFT.Contracts.stopRecording();

Replay browser responses​

Replay mode loads the recorded HTTP interactions as browser network mocks. Matching uses the request method, path, query parameters, and normalized request body when a body was captured.

ReplayBrowserContract.java
import org.openqa.selenium.By;

SHAFT.GUI.WebDriver driver = new SHAFT.GUI.WebDriver();

driver.browser().replayContract("src/test/resources/contracts/checkout.json");
driver.browser().navigateToURL("https://shop.example.test/checkout");

driver.assertThat(By.id("order-summary")).exists();
driver.quit();

Assert or verify live traffic​

Use assert mode when a contract mismatch should fail the test immediately. Use verify mode when the test should continue and collect all mismatches as report evidence.

AssertLiveContract.java
driver.browser().assertContract(
"src/test/resources/contracts/checkout.json",
"/api/");

driver.browser().navigateToURL("https://shop.example.test/checkout");
new SHAFT.API("https://shop.example.test").get("/api/cart");

SHAFT.Contracts.stopValidation();
VerifyLiveContract.java
driver.browser().verifyContract(
"src/test/resources/contracts/checkout.json",
"/api/");

driver.browser().navigateToURL("https://shop.example.test/checkout");

SHAFT.Contracts.stopValidation();

When live traffic differs from the contract, SHAFT attaches a readable HTTP Contract Diff - METHOD path artifact under allure-results and the generated Allure report under the project target output. If the request belongs to a recorded trace action, the contract entry includes the trace action id so the mismatch can be correlated with shaft-trace.json.

Redaction and normalization​

Contracts redact sensitive request and response headers, query parameters, and JSON body fields before writing to disk. Volatile values such as timestamps, request ids, trace ids, UUIDs, and configured volatile keys are normalized so stable behavior produces stable JSON.

ContractPrivacy.java
SHAFT.Properties.api.set()
.contractSensitiveKeys("authorization,cookie,password,token,api-key")
.contractVolatileKeys("requestId,traceId,timestamp,etag");

Keep recorded contracts in test resources or a dedicated fixtures directory. Do not commit production secrets, session-specific personal data, or contracts captured from environments that do not allow test evidence retention.

Verify​

  • After a recording run, the contract JSON exists at the path you passed. Sensitive headers, query parameters, and body fields are redacted, and volatile values are normalized.
  • A replay run passes with the recorded responses served as browser network mocks.
  • In assert or verify mode, change the live behavior (or edit one recorded value) and rerun. The report attaches an HTTP Contract Diff - METHOD path artifact. Assert mode fails immediately, and verify mode collects every mismatch.