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.
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.
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").perform();
SHAFT.Contracts.stopRecording();
driver.quit();
}
}
For API-only flows, use the facade directly:
SHAFT.Contracts.startRecording(
"src/test/resources/contracts/catalog.json",
"/api/catalog");
new SHAFT.API("https://shop.example.test")
.get("/api/catalog")
.perform();
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.
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.
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").perform();
SHAFT.Contracts.stopValidation();
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.
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.