Successfully migrated all Device Users end-to-end tests from WebDriverIO (wdio) to Cypress as part of the larger wdio-to-Cypress migration effort.
- ✅
device-users.add.spec.ts→device-users.add.spec.cy.ts(6 tests) - ✅
device-users.edit.spec.ts→device-users.edit.spec.cy.ts(4 tests) - ✅
device-users.delete.spec.ts→device-users.delete.spec.cy.ts(2 tests)
Total: 12 test scenarios successfully migrated
- Original wdio tests:
eform-client/e2e/Tests/device-users/ - New Cypress tests:
eform-client/cypress/e2e/d/ - Shared Page Object:
eform-client/cypress/e2e/DeviceUsers.page.ts(existing, no changes needed)
All original test scenarios preserved:
-
✅ Should add new device user with first name and last name
- Creates a device user with both required fields
- Verifies row count increases by 1
- Validates first name and last name are correctly saved
-
✅ Should NOT add device user with only first name (validation)
- Opens create modal
- Enters only first name
- Verifies save button is disabled
- Cancels operation
-
✅ Should NOT add device user with only last name (validation)
- Opens create modal
- Enters only last name
- Verifies save button is disabled
- Cancels operation
-
✅ Should NOT add device user without first and last names (validation)
- Opens create modal
- Leaves both fields empty
- Verifies save button is disabled
- Cancels operation
-
✅ Should NOT create user if cancel was clicked
- Opens create modal
- Clicks cancel
- Verifies row count remains unchanged
-
✅ Should clean up created test data
- Finds the test user created in test #1
- Deletes it
- Verifies row count returns to original value
All original test scenarios preserved:
-
✅ Should edit device user's first name
- Creates a test user in
beforehook - Edits only the first name
- Verifies first name changed, last name unchanged
- Creates a test user in
-
✅ Should edit device user's last name
- Edits only the last name
- Verifies last name changed, first name unchanged
-
✅ Should edit both first name and last name
- Edits both fields simultaneously
- Verifies both fields updated correctly
-
✅ Should not change first name and last name if cancel was clicked
- Opens edit modal
- Changes both fields
- Clicks cancel
- Verifies no changes were saved
All original test scenarios preserved:
-
✅ Should not delete device user if cancel was clicked
- Creates a test user in
beforehook - Clicks delete button
- Clicks cancel on confirmation modal
- Verifies user still exists and count unchanged
- Creates a test user in
-
✅ Should delete device user successfully
- Clicks delete button
- Confirms deletion
- Verifies user is deleted and count decreased by 1
-
Test Structure
- Used
describeblocks to group related tests - Used
beforehooks for test setup (login, navigation, test data creation) - Used arrow functions
() =>instead ofasync () =>(Cypress handles async automatically)
- Used
-
Element Selection
- Migrated from
$('#selector')tocy.get('#selector') - Used chainable assertions:
.should('be.visible'),.should('be.enabled'),.should('be.disabled')
- Migrated from
-
Waiting Strategies
- Removed explicit
browser.pause()calls - Used
cy.get('#spinner-animation').should('not.exist')to wait for loading - Leveraged Cypress's built-in retry-ability for element assertions
- Removed explicit
-
Assertions
- Migrated from
expect(actual).equal(expected)toexpect(actual).to.equal(expected) - Used Chai assertions as imported:
import { expect } from 'chai';
- Migrated from
-
Page Object Usage
- Reused existing
DeviceUsers.page.tsCypress page object - Leveraged
deviceUsersPage.Navbar.goToDeviceUsersPage()for navigation - Used
deviceUsersPage.rowNum()for counting table rows
- Reused existing
-
Test Data Generation
- Used existing
generateRandmString()helper function fromhelper-functions.ts - Used
Guid.create().toString()for unique identifiers (matching wdio approach)
- Used existing
- ✅ All tests pass ESLint validation
- ✅ Code follows existing Cypress test patterns in the repository
- ✅ Proper use of TypeScript types and imports
- ✅ Clear and descriptive test names
- ✅ Inline comments for complex operations
- ✅ Consistent formatting and style
- Tests will run automatically in the existing CI/CD pipeline
- Located in matrix test group 'd':
.github/workflows/dotnet-core-pr.yml - Execution command:
cypress/e2e/d/*(runs all tests in directory d)
- Original tests remain in
wdio-headless-step2f.conf.ts - Tests will continue to run in wdio until full migration is complete
- Can be removed after Cypress tests are verified in CI/CD
- ✅ All 12 test scenarios migrated and match original functionality
- ✅ Tests follow Cypress best practices and patterns
- ✅ ESLint validation passed with no errors
- ✅ TypeScript compilation successful
- ✅ Test file naming convention followed (*.spec.cy.ts)
- ✅ Tests organized in correct directory (cypress/e2e/d/)
- ✅ Page objects properly reused
- ✅ WDIO_TO_CYPRESS_MIGRATION.md updated
- ✅ Migration progress tracked (25/38 total tests, +10.7%)
| Aspect | wdio | Cypress |
|---|---|---|
| Async/Await | Required (async/await) |
Not needed (automatic) |
| Element Selection | $('#id') or await $('#id') |
cy.get('#id') |
| Waits | element.waitForDisplayed() |
.should('be.visible') |
| Browser Pause | browser.pause(500) |
cy.wait(500) (minimal use) |
| Assertions | expect(a).equal(b) |
expect(a).to.equal(b) |
| Test Setup | before(async () => {}) |
before(() => {}) |
- Faster Test Execution: Cypress tests typically run faster than wdio
- Better Debugging: Built-in time-travel debugging and screenshots
- Improved Reliability: Automatic waiting and retry logic reduces flakiness
- Modern Tooling: Better IDE support and developer experience
- Easier Maintenance: Simpler syntax and less boilerplate code
- Original wdio tests can be removed once all tests are migrated
- Consider adding more comprehensive error scenarios
- Potential for additional API mocking with
cy.intercept()
- Cypress Best Practices
- Migration from WebDriverIO
- WDIO_TO_CYPRESS_MIGRATION.md - Overall migration tracking