This episode covers isolating test data and environments, running tests with secure credentials, avoiding flakiness with stable selectors, and monitoring and maintaining suite reliability in the long term.

Stable and secure tests are two sides of the same coin. Episode 13 covers isolating test data and environments, managing secret credentials, choosing stable selectors, and monitoring practices to keep the suite reliable.
A suite that frequently fails makes the team lose trust and eventually ignore the tests. Poor security, on the other hand, can leak real data. Both must be addressed early.
Never run tests against production. Set up a dedicated environment whose data can be reset without risk:
npx cypress run --env apiBaseUrl=https://staging.example.com--env apiBaseUrl=https://staging.example.com points tests at staging. Make sure staging uses a separate dataset that tests are allowed to destroy, not a copy of real user data.
Isolation also means test data should not affect each other. Use unique data per test and always clean up:
it("membuat akun baru", () => {
const email = `user-${Date.now()}@example.com`;
cy.get("[data-cy=email]").type(email);
cy.get("[data-cy=submit]").click();
cy.contains(email).should("be.visible");
});user-${Date.now()}@example.com guarantees a unique email on every run. Unique data prevents collisions with other tests running at the same time, especially when parallelizing in episode 14.
Credentials must not be written in spec files that end up in the repository. Store them in the environment and read them with Cypress.env:
export CYPRESS_USER_PASSWORD='rahasia-yang-sangat-aman'
npx cypress runCYPRESS_USER_PASSWORD is stored in the CI environment or on your local machine, not in the repository. Access it in tests with Cypress.env:
cy.get("[data-cy=password]").type(Cypress.env("USER_PASSWORD"));Cypress.env("USER_PASSWORD") reads the value from the environment. Make sure files holding secrets are in .gitignore and never committed.
For most tests, use dummy credentials created specifically for testing — not real admin accounts. Separate accounts by role so tests do not depend on privileges that can change at any time.
Test stability is largely determined by selectors. Prioritize ones that do not change during development:
cy.get("[data-cy=submit-login]").click();[data-cy=submit-login] is an attribute made for testing. Unlike classes or ids that often change, data-cy is stable against styling changes and DOM refactors.
Some patterns should be avoided:
cy.get(".btn.btn-primary.mx-auto").click();
cy.get("#password").type("x");
cy.get("div > div > form > button").click();The selector .btn.btn-primary.mx-auto depends on classes that are prone to change, while the chain div > div > form > button is fragile against DOM structure changes. Replace all of them with team-agreed data-cy attributes.
Reliability is not a static state. Monitor your suite's metrics over time — pass rate, duration, number of flaky tests:
Pass rate: 98%
Durasi rata-rata: 6m 12s
Flaky test minggu ini: 3The metric Pass rate: 98% gives a picture of suite health. If the number drops, do not let it slide; address it quickly before the team loses trust.
When a test fails occasionally for no clear reason, flag it and categorize it instead of silently deleting it:
it.skip("masih diselidiki karena flaky", () => {
cy.visit("/analitik");
});it.skip(...) temporarily disables a test while recording the reason. A disabled test with a clear reason is better than a mislead failure in every run.
Info
Security and stability reinforce each other: secure credentials keep data under control, and controlled data makes tests more deterministic. Treat both as one habit, not two separate tasks.
Episode 13 strengthened the quality foundation: isolating test data and environments, secure credentials via env vars, stable data-cy selectors, and monitoring to keep the suite reliable in the long term.
Key takeaways:
data-cy for stable selectors.In the next episode, episode 14, we will cover CI/CD integration — integrating Cypress into GitHub Actions, GitLab CI, and Jenkins, headless mode versus headed runs, uploading video and screenshot artifacts, and parallelization and flaky test handling.