| name | ecs-user-setup |
| description | Expert guide for setting up users in Enhanced Consortia Support (ECS) tests. Use when generating or reviewing Cypress tests where ecs_enabled is true in TestRail, or when user mentions consortia/ECS/multi-tenant tests. |
When to Use This Skill
Invoke this skill when:
- TestRail test case has
ecs_enabled: true
- User mentions "consortia test", "ECS test", or "multi-tenant test"
- Test involves multiple tenants (Central, College, University)
- Test requires affiliation switching or cross-tenant operations
- Reviewing/debugging user creation/deletion in consortia tests
DO NOT use this skill for regular (non-ECS) tests.
Core Principles
Principle 0: TestRail Preconditions Are Law
ALWAYS create users in the tenant specified by TestRail preconditions.
- TestRail says "User A has been created in member-1 tenant" → Create in College tenant
- TestRail says "User B has been created in central tenant" → Create in Central tenant
- ECS rules supplement TestRail requirements - they NEVER override them
Principle 1: User Creation Tenant Context
Users must be created in the exact tenant specified by TestRail preconditions.
Implementation:
cy.setTenant(Affiliations.College);
cy.createTempUser([permissions_for_member1]).then((userProperties) => {
userA = userProperties;
});
cy.resetTenant();
cy.createTempUser([permissions_for_central]).then((userProperties) => {
userB = userProperties;
});
Key Constants:
Affiliations.College = member-1 tenant
Affiliations.University = member-2 tenant
cy.resetTenant() = Central (Consortia) tenant (default)
Principle 2: Login Tenant Context (Primary Affiliation)
Users automatically log into their PRIMARY AFFILIATION - the tenant where they were created.
CRITICAL FOR TEST DESIGN: If a test needs to work in a specific tenant from the start (without UI affiliation switching), create the user in that tenant.
Primary Affiliation Rules:
- The tenant where a user is created becomes their primary affiliation
- UI login automatically opens the primary affiliation tenant
- To avoid affiliation switching in tests, create users in the tenant where they'll primarily work
Design Pattern:
cy.setTenant(Affiliations.College);
cy.createTempUser([permissions]).then((userProperties) => {
userA = userProperties;
});
cy.resetTenant();
cy.createTempUser([permissions]).then((userProperties) => {
userA = userProperties;
});
When Affiliation Switch IS Needed:
If TestRail requires login to a different tenant than primary affiliation:
- User logs in (automatically to creation tenant = primary affiliation)
- User must switch affiliation in UI using
ConsortiumManager.switchActiveAffiliation()
Example:
cy.resetTenant();
cy.login(userA.username, userA.password);
ConsortiumManager.switchActiveAffiliation(tenantNames.college, tenantNames.central);
Tenant Name Constants:
tenantNames.central = "Consortia"
tenantNames.college = "College"
tenantNames.university = "University"
Principle 3: User Deletion Tenant Context
Always delete users from the same tenant they were originally created in.
after('Delete test data', () => {
cy.getAdminToken();
cy.setTenant(Affiliations.College);
Users.deleteViaApi(userA.userId);
cy.resetTenant();
Users.deleteViaApi(userB.userId);
});
Principle 4: Automatic Central Affiliation
Users created by admin automatically get Central (Consortia) affiliation.
- NEVER manually assign Central affiliation - it's automatic
- Only manually assign member tenant affiliations (College, University)
- Use
cy.assignAffiliationToUser() for member affiliations only
cy.assignAffiliationToUser(Affiliations.Consortia, userA.userId);
cy.assignAffiliationToUser(Affiliations.College, userA.userId);
cy.assignAffiliationToUser(Affiliations.University, userA.userId);
Complete Implementation Pattern
Standard ECS User Setup
describe('ECS Test Example', () => {
const testData = {};
let userA;
let userB;
before('Create test data', () => {
cy.getAdminToken();
cy.setTenant(Affiliations.College);
cy.createTempUser([
Permissions.inventoryAll.gui,
Permissions.uiQuickMarcQuickMarcBibliographicEditorAll.gui,
]).then((userProperties) => {
userA = userProperties;
cy.resetTenant();
cy.assignPermissionsToExistingUser(userA.userId, [
Permissions.consortiaSettingsConsortiumManagerView.gui,
]);
cy.assignAffiliationToUser(Affiliations.University, userA.userId);
});
cy.();
cy.([
..,
]).( {
userB = userBProperties;
cy.(., userB.);
});
});
(, {
: [, , ]
}, {
cy.();
cy.(userA., userA., {
: .,
: .,
});
.(tenantNames., tenantNames.);
});
(, {
cy.();
cy.(.);
.(userA.);
cy.();
.(userB.);
});
});
Primary Affiliation Design Patterns
Pattern 1: Test Works in User's Primary Affiliation (No Switch Needed)
When test needs to work in Member tenant from the start:
before('Create test data', () => {
cy.getAdminToken();
cy.setTenant(Affiliations.College);
cy.createTempUser([permissions_for_college]).then((userProperties) => {
testUser = userProperties;
cy.resetTenant();
cy.assignPermissionsToExistingUser(testUser.userId, [permissions_for_central]);
});
});
it('Test in College tenant', () => {
cy.setTenant(Affiliations.College);
cy.login(testUser.username, testUser.password, {
path: TopMenu.inventoryPath,
waiter: InventoryInstances.waitContentLoading,
});
ConsortiumManager.checkCurrentTenantInTopMenu(tenantNames.college);
});
Pattern 2: Test Requires Affiliation Switch
When test needs to switch between tenants:
before('Create test data', () => {
cy.getAdminToken();
cy.setTenant(Affiliations.College);
cy.createTempUser([permissions_for_college]).then((userProperties) => {
testUser = userProperties;
cy.resetTenant();
cy.assignPermissionsToExistingUser(testUser.userId, [permissions_for_central]);
});
});
it('Test switches from College to Central', () => {
cy.resetTenant();
cy.login(testUser.username, testUser.password, {
path: TopMenu.inventoryPath,
waiter: InventoryInstances.waitContentLoading,
});
ConsortiumManager.switchActiveAffiliation(tenantNames.college, tenantNames.central);
ConsortiumManager.checkCurrentTenantInTopMenu(tenantNames.central);
});
ECS with Capabilities (Eureka Platform)
before('Create test data', () => {
cy.getAdminToken();
const capabsToAssign = [Capabilities.settingsEnabled];
const capabSetsToAssign = [
CapabilitySets.uiAuthorizationRolesSettingsView,
];
cy.setTenant(Affiliations.College);
cy.createTempUser([]).then((userProperties) => {
testData.user = userProperties;
cy.assignCapabilitiesToExistingUser(
testData.user.userId,
capabsToAssign,
capabSetsToAssign,
);
cy.resetTenant();
cy.assignCapabilitiesToExistingUser(
testData.user.userId,
[Capabilities.settingsEnabled],
[CapabilitySets.uiConsortiaSettingsView],
);
});
});
Common Patterns & Troubleshooting
Pattern: User Works in Member Tenant Only
cy.setTenant(Affiliations.College);
cy.createTempUser([permissions]).then((userProperties) => {
testData.user = userProperties;
cy.login(testData.user.username, testData.user.password);
});
Pattern: User Created in Central, Works in Central
cy.resetTenant();
cy.createTempUser([permissions]).then((userProperties) => {
testData.user = userProperties;
cy.login(testData.user.username, testData.user.password);
});
Pattern: Multiple Users, Different Tenants
let centralUser;
let collegeUser;
let universityUser;
cy.resetTenant();
cy.createTempUser([centralPermissions]).then((user) => {
centralUser = user;
});
cy.setTenant(Affiliations.College);
cy.createTempUser([collegePermissions]).then((user) => {
collegeUser = user;
});
cy.setTenant(Affiliations.University);
cy.createTempUser([universityPermissions]).then((user) => {
universityUser = user;
});
after('Delete test data', () => {
cy.getAdminToken();
cy.resetTenant();
Users.deleteViaApi(centralUser.userId);
cy.setTenant(Affiliations.College);
Users.deleteViaApi(collegeUser.userId);
cy.setTenant(Affiliations.University);
Users.deleteViaApi(universityUser.userId);
});
Troubleshooting: User Can't See Data in Target Tenant
Problem: User switches to Central but can't see expected data.
Solution: Ensure user has:
- Correct permissions assigned in target tenant
- Correct affiliation assigned (automatic for Central, manual for members)
- Switched affiliation in UI using
ConsortiumManager.switchActiveAffiliation()
Troubleshooting: User Deletion Fails
Problem: Users.deleteViaApi() fails with 404 or permission error.
Solution: Verify you're deleting from the correct tenant:
- Set tenant context to WHERE USER WAS CREATED
- Not where user logged in or worked
Required Imports for ECS Tests
import Affiliations from '../../../support/dictionary/affiliations';
import ConsortiumManager from '../../../support/fragments/consortium-manager/consortiumManager';
import { tenantNames } from '../../../support/dictionary/affiliations';
import Users from '../../../support/fragments/users/users';
import Permissions from '../../../support/dictionary/permissions';
import Capabilities from '../../../support/dictionary/capabilities';
import CapabilitySets from '../../../support/dictionary/capabilitySets';
Decision Tree for ECS User Setup
- Read TestRail Preconditions - What tenant is user created in?
- Set Tenant Context - Use
cy.setTenant() or cy.resetTenant()
- Create User - Use
cy.createTempUser() with tenant-specific permissions
- Assign Cross-Tenant Permissions - Switch to other tenants, use
cy.assignPermissionsToExistingUser()
- Assign Member Affiliations - ONLY for College/University (NOT Central)
- Login - User logs into creation tenant automatically
- Switch Affiliation If Needed - Use
ConsortiumManager.switchActiveAffiliation()
- Cleanup - Delete from creation tenant in
after() hook
Validation Checklist
Before completing ECS test implementation, verify:
Key Differences: ECS vs Non-ECS Tests
| Aspect | Non-ECS Test | ECS Test |
|---|
| User Creation | Single tenant (default) | Specific tenant via cy.setTenant() |
| Permissions | Assigned during creation | May span multiple tenants |
| Affiliations | Not relevant | Central automatic, members manual |
| Login | Direct to application | May require affiliation switch |
| Deletion | Simple deleteViaApi() | Must match creation tenant |
| Tags | smoke, criticalPath, etc. | smokeECS, criticalPathECS, etc. |
Remember
- TestRail preconditions are the source of truth - always follow them exactly
- Central affiliation is automatic - never assign it manually
- Login tenant = creation tenant - always, without exception
- Delete from creation tenant - not from where user worked
- Member affiliations are manual - use
cy.assignAffiliationToUser()
- Affiliation switch ≠ tenant context switch - UI operation vs API operation
When in doubt, refer back to TestRail preconditions and follow them literally.