<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sehani Chathurangi</title>
    <description>The latest articles on DEV Community by Sehani Chathurangi (@sehani_chathurangi).</description>
    <link>https://dev.to/sehani_chathurangi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2909863%2F7f7e7e1b-e665-4067-8ff3-565a688aa50f.jpg</url>
      <title>DEV Community: Sehani Chathurangi</title>
      <link>https://dev.to/sehani_chathurangi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sehani_chathurangi"/>
    <language>en</language>
    <item>
      <title>Building Mocks-First Automated Testing with Cypress and AWS DynamoDB</title>
      <dc:creator>Sehani Chathurangi</dc:creator>
      <pubDate>Fri, 14 Aug 2026 10:10:37 +0000</pubDate>
      <link>https://dev.to/cypress/building-mocks-first-automated-testing-with-cypress-and-aws-dynamodb-3ngh</link>
      <guid>https://dev.to/cypress/building-mocks-first-automated-testing-with-cypress-and-aws-dynamodb-3ngh</guid>
      <description>&lt;p&gt;When testing applications that depend on cloud services, manually preparing database records for every test can quickly become time-consuming, repetitive, and error-prone.&lt;/p&gt;

&lt;p&gt;A better approach is to automate test-data creation using reusable fixtures, custom Cypress tasks, and the AWS SDK.&lt;/p&gt;

&lt;p&gt;In this article, I'll walk through how I built a &lt;strong&gt;mocks-first testing approach using Cypress and AWS DynamoDB&lt;/strong&gt;, where each test can create the data it needs, execute independently, and verify the resulting database state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Mocks-First Testing?
&lt;/h2&gt;

&lt;p&gt;A mocks-first approach allows tests to control their required data and dependencies instead of relying on manually prepared records.&lt;/p&gt;

&lt;p&gt;Rather than creating database records before running a test, the test itself prepares the required state during execution.&lt;/p&gt;

&lt;p&gt;This provides several benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faster test execution&lt;/li&gt;
&lt;li&gt;Repeatable test scenarios&lt;/li&gt;
&lt;li&gt;Reusable test data&lt;/li&gt;
&lt;li&gt;Less manual setup&lt;/li&gt;
&lt;li&gt;Better test isolation&lt;/li&gt;
&lt;li&gt;Easier maintenance&lt;/li&gt;
&lt;li&gt;More reliable CI/CD execution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not to mock every AWS service. Instead, the approach focuses on &lt;strong&gt;controlling test data and external dependencies so that tests remain predictable and repeatable&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Overall Approach
&lt;/h2&gt;

&lt;p&gt;The architecture can be summarized as:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cypress Test → &lt;code&gt;cy.task()&lt;/code&gt; → Node.js → AWS SDK → DynamoDB&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Cypress test is responsible for describing the scenario and assertions, while the Node.js layer handles AWS-specific operations.&lt;/p&gt;

&lt;p&gt;This separation keeps the test code clean and prevents AWS database logic from being duplicated across test cases.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Create Reusable Mock Data
&lt;/h2&gt;

&lt;p&gt;The first step is to create reusable JSON fixtures.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cypress/
└── fixtures/
    └── test-data.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The fixture contains the information required to create the database record.&lt;/p&gt;

&lt;p&gt;Instead of hardcoding database values inside every test, the fixture becomes the base payload that can be reused across multiple scenarios.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"test-12345"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Sample Test Data"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TEST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Different fixtures can also be created for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Positive scenarios&lt;/li&gt;
&lt;li&gt;Negative scenarios&lt;/li&gt;
&lt;li&gt;Boundary conditions&lt;/li&gt;
&lt;li&gt;Error scenarios&lt;/li&gt;
&lt;li&gt;Different transaction states&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This keeps test data separate from test logic.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Separate Database Logic
&lt;/h2&gt;

&lt;p&gt;The next step is to keep DynamoDB operations outside the Cypress test itself.&lt;/p&gt;

&lt;p&gt;A dedicated helper can be responsible for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating the DynamoDB client&lt;/li&gt;
&lt;li&gt;Converting fixture data into database records&lt;/li&gt;
&lt;li&gt;Generating partition keys and sort keys&lt;/li&gt;
&lt;li&gt;Calculating TTL values&lt;/li&gt;
&lt;li&gt;Inserting records&lt;/li&gt;
&lt;li&gt;Retrieving records&lt;/li&gt;
&lt;li&gt;Deleting test data when required&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, a helper might expose operations such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;insertMockData()
getMockData()
deleteMockData()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important principle is &lt;strong&gt;separation of concerns&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The test should describe &lt;em&gt;what data it needs&lt;/em&gt;, while the helper handles &lt;em&gt;how that data is stored in DynamoDB&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Expose Database Operations Through Cypress Tasks
&lt;/h2&gt;

&lt;p&gt;Cypress provides &lt;code&gt;cy.task()&lt;/code&gt; as a bridge between the Cypress test environment and Node.js.&lt;/p&gt;

&lt;p&gt;Instead of putting AWS SDK operations directly inside the browser-side test, the test can call a custom task:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;insertMockData&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mockData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The flow becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cypress Test
     │
     ▼
 cy.task()
     │
     ▼
 Node.js
     │
     ▼
 AWS SDK
     │
     ▼
 DynamoDB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Typical Cypress tasks can include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;insertMockData&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;getMockData&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;deleteMockData&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach centralizes AWS operations and makes them reusable across the entire test suite.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: Configure Environment Variables
&lt;/h2&gt;

&lt;p&gt;Cloud configuration should never be hardcoded inside test files.&lt;/p&gt;

&lt;p&gt;Environment-specific values can be provided through configuration such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS Region&lt;/li&gt;
&lt;li&gt;AWS credentials&lt;/li&gt;
&lt;li&gt;DynamoDB table name&lt;/li&gt;
&lt;li&gt;Local DynamoDB endpoint&lt;/li&gt;
&lt;li&gt;Other environment-specific settings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This allows the same test suite to run against different environments.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Local
  ↓
Development
  ↓
QA
  ↓
CI/CD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The test logic remains unchanged while the configuration changes according to the execution environment.&lt;/p&gt;

&lt;p&gt;Credentials and secrets should always be managed securely and should never be committed to the repository.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5: Build Flexible Test Data
&lt;/h2&gt;

&lt;p&gt;Creating a separate fixture for every test scenario can eventually lead to duplicated test data.&lt;/p&gt;

&lt;p&gt;Instead, a base fixture can be loaded and overridden only where necessary.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;testData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;baseFixture&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`test-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;INACTIVE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The base fixture provides the common structure, while the test customizes only the values relevant to the scenario.&lt;/p&gt;

&lt;p&gt;This approach makes it easier to generate unique test records while keeping the fixture maintainable.&lt;/p&gt;

&lt;p&gt;It is especially useful when testing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiple transactions&lt;/li&gt;
&lt;li&gt;Different statuses&lt;/li&gt;
&lt;li&gt;Different merchants&lt;/li&gt;
&lt;li&gt;Edge cases&lt;/li&gt;
&lt;li&gt;Concurrent processing&lt;/li&gt;
&lt;li&gt;Large datasets&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 6: Verify the Database State
&lt;/h2&gt;

&lt;p&gt;Creating test data is only part of the process.&lt;/p&gt;

&lt;p&gt;After the application processes the data, the test should retrieve the relevant DynamoDB record and validate the resulting state.&lt;/p&gt;

&lt;p&gt;Typical validations include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Record exists&lt;/li&gt;
&lt;li&gt;Partition key is correct&lt;/li&gt;
&lt;li&gt;Sort key is correct&lt;/li&gt;
&lt;li&gt;Required attributes are stored&lt;/li&gt;
&lt;li&gt;Status is updated correctly&lt;/li&gt;
&lt;li&gt;Configuration values match expectations&lt;/li&gt;
&lt;li&gt;TTL is generated correctly&lt;/li&gt;
&lt;li&gt;Expected processing results are persisted&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Insert test data
       ↓
Application processes data
       ↓
Retrieve DynamoDB record
       ↓
Validate final state
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows the test to validate not only that data can be written, but also that the application's workflow produces the expected result.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Structure Works
&lt;/h2&gt;

&lt;p&gt;The approach separates the test suite into three main responsibilities:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fixtures
   ↓
Test Data

Database Helpers
   ↓
AWS / DynamoDB Operations

Cypress Tests
   ↓
Business Scenarios + Assertions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This separation provides a cleaner architecture and makes individual components easier to maintain.&lt;/p&gt;

&lt;p&gt;If the DynamoDB implementation changes, the test cases do not necessarily need to change.&lt;/p&gt;

&lt;p&gt;If the test scenario changes, the AWS helper does not need to change.&lt;/p&gt;




&lt;h2&gt;
  
  
  Moving Toward Event-Driven Testing
&lt;/h2&gt;

&lt;p&gt;Directly inserting records into DynamoDB is useful for preparing controlled test states, but it can also bypass parts of the application's normal workflow.&lt;/p&gt;

&lt;p&gt;This approach can therefore become the foundation for a more complete &lt;strong&gt;event-driven testing strategy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The current approach might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fixture
   ↓
Cypress Task
   ↓
DynamoDB
   ↓
Application / Verification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next evolution could be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fixture
   ↓
Event / SNS
   ↓
Application
   ↓
DynamoDB
   ↓
Cypress Verification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of directly creating the database record, the same mock payload can be published as an event.&lt;/p&gt;

&lt;p&gt;The application then processes the event through its normal workflow, and Cypress verifies the final database state.&lt;/p&gt;

&lt;p&gt;The biggest advantage is that the &lt;strong&gt;test-data model can remain reusable&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The injection point changes, but the underlying fixture structure can remain largely the same.&lt;/p&gt;




&lt;h2&gt;
  
  
  When This Approach Is Useful
&lt;/h2&gt;

&lt;p&gt;This pattern works particularly well for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Integration testing&lt;/li&gt;
&lt;li&gt;Event-driven applications&lt;/li&gt;
&lt;li&gt;DynamoDB-backed services&lt;/li&gt;
&lt;li&gt;CI/CD pipelines&lt;/li&gt;
&lt;li&gt;Repeatable test scenarios&lt;/li&gt;
&lt;li&gt;Large-scale automated test suites&lt;/li&gt;
&lt;li&gt;Tests requiring controlled database state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, direct database seeding should be used carefully for end-to-end testing because it can bypass application logic that you may actually want to validate.&lt;/p&gt;

&lt;p&gt;A good testing strategy can use both approaches:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Database seeding&lt;/strong&gt; for controlled setup and targeted integration tests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Event/API-driven setup&lt;/strong&gt; for validating the application's complete workflow.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Benefits
&lt;/h2&gt;

&lt;p&gt;Using reusable fixtures together with Cypress tasks provides several advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cleaner test code&lt;/strong&gt; — AWS logic stays outside the test cases.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reusable mock data&lt;/strong&gt; — Fixtures can support many scenarios.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduced duplication&lt;/strong&gt; — Base data can be overridden when needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Faster execution&lt;/strong&gt; — Tests do not depend on manual database preparation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better test isolation&lt;/strong&gt; — Each test can create its own required state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Centralized AWS logic&lt;/strong&gt; — DynamoDB operations are maintained in one place.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI/CD friendly&lt;/strong&gt; — Test data can be generated automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easy evolution&lt;/strong&gt; — The same data model can support future event-driven testing.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Automating database setup with reusable fixtures, Cypress tasks, and the AWS SDK can remove a significant amount of repetitive manual work from integration testing.&lt;/p&gt;

&lt;p&gt;The key is to keep &lt;strong&gt;test data, database operations, and test scenarios separate&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of manually preparing DynamoDB records before every test, the test suite becomes responsible for creating the state it needs and validating the resulting behavior.&lt;/p&gt;

&lt;p&gt;More importantly, this approach creates a foundation for moving toward event-driven testing. As the application architecture evolves, the same reusable test data can be injected through events and processed through the application's normal workflow.&lt;/p&gt;

&lt;p&gt;The result is a testing architecture that is &lt;strong&gt;repeatable, maintainable, scalable, and easier to integrate into CI/CD pipelines&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>cypress</category>
      <category>aws</category>
      <category>testing</category>
      <category>automation</category>
    </item>
    <item>
      <title>Connecting AWS Account with Cypress Automation: A Simple STS Connection Test</title>
      <dc:creator>Sehani Chathurangi</dc:creator>
      <pubDate>Fri, 17 Jul 2026 12:42:14 +0000</pubDate>
      <link>https://dev.to/cypress/connecting-aws-account-with-cypress-automation-a-simple-sts-connection-test-aea</link>
      <guid>https://dev.to/cypress/connecting-aws-account-with-cypress-automation-a-simple-sts-connection-test-aea</guid>
      <description>&lt;p&gt;When building Cypress automation that interacts with AWS services, the first step is verifying that your test framework can successfully authenticate and communicate with your AWS account.&lt;/p&gt;

&lt;p&gt;In this article, you'll learn how to connect Cypress to AWS and perform a simple authentication test using AWS Security Token Service (STS) and the &lt;code&gt;GetCallerIdentity&lt;/code&gt; API.&lt;/p&gt;

&lt;p&gt;This approach helps confirm that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS credentials are correctly configured.&lt;/li&gt;
&lt;li&gt;Cypress can invoke AWS SDK operations through Node.js tasks.&lt;/li&gt;
&lt;li&gt;The automation environment is connected to the expected AWS account.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Establishing this connection first provides a solid foundation before automating interactions with services such as AWS Lambda, Amazon S3, Amazon DynamoDB, Amazon SNS, or Amazon SQS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before getting started, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js installed&lt;/li&gt;
&lt;li&gt;A Cypress project&lt;/li&gt;
&lt;li&gt;Valid AWS credentials:

&lt;ul&gt;
&lt;li&gt;AWS Access Key ID&lt;/li&gt;
&lt;li&gt;AWS Secret Access Key&lt;/li&gt;
&lt;li&gt;AWS Session Token (if using temporary credentials)&lt;/li&gt;
&lt;li&gt;AWS Region&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Note:If you're running Cypress in an AWS environment (such as AWS CodeBuild, an EC2 instance with an IAM role, or GitHub Actions using OpenID Connect), you may not need to provide credentials manually. The AWS SDK can automatically retrieve credentials from the execution environment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Install the AWS SDK&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install the AWS STS client package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @aws-sdk/client-sts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this connectivity test, we only need the AWS Security Token Service (STS) client.&lt;/p&gt;

&lt;p&gt;The package provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;STSClient&lt;/code&gt; – Creates a client for communicating with AWS STS.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GetCallerIdentityCommand&lt;/code&gt; – Returns details about the authenticated AWS identity associated with the configured credentials.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Configure AWS Credentials&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For local development, create or update your &lt;code&gt;cypress.env.json&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"AWS_ACCESS_KEY_ID"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"AWS_SECRET_ACCESS_KEY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"AWS_SESSION_TOKEN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"AWS_REGION"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Populate the file with your AWS credentials.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"AWS_ACCESS_KEY_ID"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your-access-key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"AWS_SECRET_ACCESS_KEY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your-secret-key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"AWS_SESSION_TOKEN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your-session-token"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"AWS_REGION"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; Never commit &lt;code&gt;cypress.env.json&lt;/code&gt; containing real AWS credentials to source control. Add it to your &lt;code&gt;.gitignore&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practice:&lt;/strong&gt; For CI/CD pipelines, prefer environment variables, IAM roles, or OpenID Connect (OIDC) instead of storing credentials in a file.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Configure Cypress to Use AWS Credentials&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Update your &lt;code&gt;cypress.config.ts&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;First, import the required AWS SDK classes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cypress&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;STSClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GetCallerIdentityCommand&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@aws-sdk/client-sts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside &lt;code&gt;setupNodeEvents&lt;/code&gt;, map the Cypress environment variables to Node.js environment variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;setupNodeEvents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;awsKeys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;AWS_SESSION_TOKEN&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;AWS_REGION&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;awsKeys&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cypress stores environment variables in &lt;code&gt;config.env&lt;/code&gt;, while the AWS SDK automatically reads credentials from the standard Node.js environment (&lt;code&gt;process.env&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;By copying the values into &lt;code&gt;process.env&lt;/code&gt;, the AWS SDK can authenticate automatically without requiring any additional credential configuration.&lt;/p&gt;

&lt;p&gt;The AWS SDK follows the AWS Credential Provider Chain, and environment variables are one of the first credential sources it checks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Create an AWS Connection Task&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a Cypress task that authenticates with AWS using STS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;task&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;awsConnectionTest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;STSClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AWS_REGION&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;us-east-1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GetCallerIdentityCommand&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;Arn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Arn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;UserId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;UserId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`AWS authentication failed: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why use a Cypress task?
&lt;/h3&gt;

&lt;p&gt;AWS SDK calls must run in Cypress tasks because tasks execute in the Node.js process.&lt;/p&gt;

&lt;p&gt;Cypress test code runs in the browser context, where direct access to Node.js APIs is not available. Using &lt;code&gt;cy.task()&lt;/code&gt; allows your tests to securely execute backend operations such as invoking AWS services.&lt;/p&gt;

&lt;h3&gt;
  
  
  What happens during this task?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Cypress calls the &lt;code&gt;awsConnectionTest&lt;/code&gt; task.&lt;/li&gt;
&lt;li&gt;The AWS SDK creates an STS client using the configured region.&lt;/li&gt;
&lt;li&gt;The SDK automatically resolves credentials from the environment.&lt;/li&gt;
&lt;li&gt;AWS validates the credentials.&lt;/li&gt;
&lt;li&gt;STS returns details about the authenticated IAM user or role.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A successful response looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Account"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"123456789012"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Arn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:iam::123456789012:user/test-user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"UserId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AIDAxxxxxxxx"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 5: Create a Cypress Test&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a new test file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;testing/awsConnection.cy.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;AWS connection&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;connects to AWS using STS GetCallerIdentity&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;awsConnectionTest&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

      &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

      &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Account&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Arn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UserId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 6: Run the Cypress Test&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Execute either of the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx cypress open
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx cypress run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If authentication is successful, Cypress logs the authenticated AWS identity, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS Account ID&lt;/li&gt;
&lt;li&gt;IAM User or Role ARN&lt;/li&gt;
&lt;li&gt;User ID&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This confirms that Cypress can successfully authenticate with your AWS account.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Start with GetCallerIdentity?
&lt;/h3&gt;

&lt;p&gt;Before interacting with AWS services such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS Lambda&lt;/li&gt;
&lt;li&gt;Amazon S3&lt;/li&gt;
&lt;li&gt;Amazon DynamoDB&lt;/li&gt;
&lt;li&gt;Amazon SNS&lt;/li&gt;
&lt;li&gt;Amazon SQS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;it's recommended to verify that authentication is working correctly.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;GetCallerIdentity&lt;/code&gt; is ideal because it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Confirms that authentication is successful.&lt;/li&gt;
&lt;li&gt;Identifies the AWS account and IAM identity being used.&lt;/li&gt;
&lt;li&gt;Helps diagnose credential-related issues early.&lt;/li&gt;
&lt;li&gt;Does not require permissions beyond the ability to authenticate.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Successfully calling &lt;code&gt;GetCallerIdentity&lt;/code&gt; confirms that Cypress can authenticate with AWS using the configured credentials.&lt;/p&gt;

&lt;p&gt;In this article, you learned how to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install the AWS STS SDK.&lt;/li&gt;
&lt;li&gt;Configure AWS credentials for local development.&lt;/li&gt;
&lt;li&gt;Map Cypress environment variables to the Node.js environment.&lt;/li&gt;
&lt;li&gt;Create a Cypress task that authenticates with AWS.&lt;/li&gt;
&lt;li&gt;Validate the connection using &lt;code&gt;GetCallerIdentity&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once this authentication step is working, you can extend the same approach to automate testing against other AWS services such as Lambda functions, S3 buckets, DynamoDB tables, SNS topics, SQS queues, and many more.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>aws</category>
      <category>testing</category>
      <category>cypress</category>
    </item>
    <item>
      <title>Reusing Dynamic Values in Cypress Tests: Store Once, Reuse Anywhere</title>
      <dc:creator>Sehani Chathurangi</dc:creator>
      <pubDate>Fri, 11 Jul 2025 03:54:11 +0000</pubDate>
      <link>https://dev.to/cypress/reusing-dynamic-values-in-cypress-tests-store-once-reuse-anywhere-3e4m</link>
      <guid>https://dev.to/cypress/reusing-dynamic-values-in-cypress-tests-store-once-reuse-anywhere-3e4m</guid>
      <description>&lt;p&gt;In test automation, maintaining and reusing state between test cases is essential for creating efficient, end-to-end workflows. When writing Cypress tests that interact with APIs, it's common to receive dynamic data from a response—such as an ID, token, or reference number—that you'll need to use in a later request. Instead of hardcoding or repeating logic, Cypress allows you to &lt;strong&gt;store these values temporarily&lt;/strong&gt; during the test run and reuse them wherever needed.&lt;/p&gt;

&lt;p&gt;Let’s explore how to do this in a clean and efficient way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Store Values Dynamically?
&lt;/h2&gt;

&lt;p&gt;Many real-world scenarios involve multi-step processes where the output of one step is the input for the next. For instance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A request may return an identifier (id) that’s required for the next API call.&lt;/li&gt;
&lt;li&gt;A system may provide an access token that must be included in subsequent headers.&lt;/li&gt;
&lt;li&gt;You might need to retrieve the status of a resource using a previously returned reference.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;By reusing these variables, you:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduce redundancy: Avoid recreating the same data in every test.&lt;/li&gt;
&lt;li&gt;Improve performance: Skip repetitive setup steps.&lt;/li&gt;
&lt;li&gt;Mimic real-world workflows: Simulate multi-step user journeys.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  01.Use Cypress.env() to Store and Reuse Data
&lt;/h2&gt;

&lt;p&gt;Cypress provides a convenient way to store values in memory using Cypress.env() during a test run.&lt;/p&gt;

&lt;h3&gt;
  
  
  Store the Value
&lt;/h3&gt;

&lt;p&gt;When you receive a value from an API response, you can store it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cy.request('POST', 'your-api-url', requestBody).then((response) =&amp;gt; {
  const dynamicId = response.body.id;
  Cypress.env('dynamicId', dynamicId); // Save it temporarily
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Reuse It in Another Request
&lt;/h3&gt;

&lt;p&gt;You can then access that value in a later test step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cy.request({
  method: 'GET',
  url: `your-api-url/${Cypress.env('dynamicId')}`,
  headers: {
    Authorization: `Bearer yourAccessToken`,
  },
}).then((response) =&amp;gt; {
  expect(response.status).to.eq(200);
  // more assertions
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example with Tokens&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here’s how to store an access token received from an authorization request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cy.request('POST', 'token-url', credentials).then((response) =&amp;gt; {
  const token = response.body.access_token;
  Cypress.env('accessToken', token); // Stored in memory
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Use it later:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cy.request({
  method: 'GET',
  url: 'api/secure-data',
  headers: {
    Authorization: `Bearer ${Cypress.env('accessToken')}`, // Used here
  },
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  02.Using Test-Specific Variables
&lt;/h2&gt;

&lt;p&gt;For data needed only within a single test file, use closures (e.g., let variables).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Reusing a Resource ID&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;describe('Reusing ResourceID Tests', () =&amp;gt; {
  let resourceId; // Accessible across all tests in this describe block
  it('Creates a Resource', () =&amp;gt; {
    cy.request('/resources', { method: 'POST' }).then((response) =&amp;gt; {
      resourceId = response.body.id; // Assign ID
    });
  });
  it('Validates the Resource', () =&amp;gt; {
    cy.request(`/resources/${resourceId}`).then((response) =&amp;gt; {
      expect(response.status).to.eq(200);
    });
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  03. External Storage (Files, Databases)
&lt;/h2&gt;

&lt;p&gt;For cross-suite or cross-run persistence, save data to files (e.g., JSON) or databases. Use this sparingly, as it introduces external dependencies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use Cypress.env() for temporary values within the same test suite.&lt;/li&gt;
&lt;li&gt;Do not use Cypress.env() as a way to persist values between test files.&lt;/li&gt;
&lt;li&gt;Store static configuration in cypress.env.json, but store dynamic values using Cypress.env() at runtime.&lt;/li&gt;
&lt;li&gt;Clean Up State: Delete test data after runs (e.g., in after hooks).&lt;/li&gt;
&lt;li&gt;Avoid Hardcoding Values: Use environment variables or configuration files for URLs, keys, etc.&lt;/li&gt;
&lt;li&gt;Handle Asynchronous Flows: Use cy.wait() or retry logic if systems need time to process data.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Storing dynamic data during test execution helps avoid hardcoding and keeps your Cypress tests clean and reliable. By leveraging Cypress environment variables, closures, or external storage, you can build robust test suites that minimize redundancy and maximize efficiency. Always prioritize clarity and maintainability—use descriptive variable names and document shared state dependencies. This approach improves test reusability, enhances readability, and supports more complex workflows in your automation suite.&lt;/p&gt;

&lt;p&gt;👉 For more articles like this, visit my site: &lt;a href="https://careersuccesso.com/" rel="noopener noreferrer"&gt;https://careersuccesso.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cypress</category>
      <category>testing</category>
      <category>automation</category>
      <category>qa</category>
    </item>
    <item>
      <title>Mastering Test Flow Control with Cypress.stop()</title>
      <dc:creator>Sehani Chathurangi</dc:creator>
      <pubDate>Tue, 29 Apr 2025 15:18:08 +0000</pubDate>
      <link>https://dev.to/cypress/mastering-test-flow-control-with-cypressstop-1aph</link>
      <guid>https://dev.to/cypress/mastering-test-flow-control-with-cypressstop-1aph</guid>
      <description>&lt;p&gt;Cypress is a powerful tool for end-to-end testing, but sometimes you need to halt execution immediately when a critical failure occurs. Enter Cypress.stop(). This command stops all test execution, ensuring you avoid cascading failures or wasted resources when a prerequisite fails. Let’s explore how to use it effectively. When working with automated tests in Cypress, efficiency is everything—especially when you're running large test suites across multiple environments or CI pipelines. That’s where Cypress's Cypress.stop() method becomes incredibly useful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Cypress.stop()?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Cypress.stop() halts the Cypress Test Runner mid-execution. It’s a manual switch to stop running &lt;strong&gt;any remaining tests&lt;/strong&gt; in the current spec file.&lt;/p&gt;

&lt;p&gt;It can be incredibly handy in situations like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When an essential precondition fails (e.g., token generation, environment setup)&lt;/li&gt;
&lt;li&gt;When you want to stop on the &lt;strong&gt;first failure&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;To prevent redundant test execution during debugging or early failure diagnosis&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Syntax&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cypress.stop()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example Scenario: Stop Test Run on Token Generation Failure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s say you’re working on API tests.&lt;/p&gt;

&lt;p&gt;In this API test, Cypress.stop() is used to halt execution if an access token can’t be generated. Without this token, other tests verifying are meaningless. Here’s the breakdown:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;it('Generates an Access Token', () =&amp;gt; {
  cy.request({
    method: 'POST',
    url: `${Cypress.env('baseUrl')}`,
    headers: {
      'subscription-Key': `${Cypress.env('subscriptionKey')}`,
      Authorization:
        'Basic ' +
        btoa(
          `${Cypress.env('apiUser')}:${Cypress.env('apiKey')}`
        ),
    },
    failOnStatusCode: false,
  }).then((response) =&amp;gt; {
    if (response.status !== 200 || !response.body.access_token) {
      cy.log('Access token generation failed!');
      Cypress.stop(); //Stop remaining tests in the file
    }
    cy.log(‘Access token generated successfully');
    Cypress.env('accessToken', response.body.access_token);
  });
});
// ... other tests that depend on the access token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Stop Tests After Any Failure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want to &lt;strong&gt;automatically stop the test run on any failure&lt;/strong&gt;, add this to your automation script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;afterEach(function () {
  if (this.currentTest.state === 'failed') {
    Cypress.stop();
  }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Behavior Differences: cypress run vs cypress open&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;cypress run (CI mode):&lt;/strong&gt;Cypress.stop() halts execution of the current spec file, but the app continues running and uploads all test results.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj2smcyew5z6grg46pniu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj2smcyew5z6grg46pniu.png" alt="cypress run (CI mode)" width="800" height="166"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;cypress open (Interactive mode):&lt;/strong&gt; Cypress will stop executing tests but keep the Test Runner open for inspection.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F07f7swt0fzq5p2v65hse.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F07f7swt0fzq5p2v65hse.png" alt="cypress open (Interactive mode)" width="800" height="204"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why This Works&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fail-Fast Principle: The test suite stops immediately on token failure, avoiding false negatives in later steps.&lt;/li&gt;
&lt;li&gt;Clear Diagnostics: Logs the failure and stops execution, making debugging easier.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When to Use Cypress.stop() vs. cy.skip()&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cypress.stop():&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nuclear option: Stops ALL tests.&lt;/li&gt;
&lt;li&gt;Use when no further tests can proceed (e.g., missing tokens, broken environments).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;cy.skip():&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Skips a single test or block.&lt;/li&gt;
&lt;li&gt;Use when a test is conditionally irrelevant (e.g., a feature flag is off).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cypress.stop() is simple but powerful for controlling your test flow when you know something has gone wrong. It's especially useful during development or in CI pipelines to avoid wasting resources.&lt;/p&gt;

&lt;p&gt;Cypress.stop() is your emergency brake for tests. By using it in scenarios like failed logins, broken API handshakes, or missing environment variables, you keep your test results clean and actionable. Pair it with robust error logging, and you’ll streamline your debugging process while saving time and resources.&lt;/p&gt;

</description>
      <category>cypress</category>
      <category>automation</category>
      <category>testing</category>
      <category>softwaretesting</category>
    </item>
  </channel>
</rss>
