Skip to content

Commit 810415a

Browse files
authored
Merge pull request #1294 from bcgov/stories/ecer-5023
Stories/ecer 5023 - Cypress Automated tests - Labour mobility workflows
2 parents 6224a11 + 1ec037a commit 810415a

File tree

49 files changed

+1861
-69
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1861
-69
lines changed
Lines changed: 153 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,169 @@
1-

2-
using Microsoft.AspNetCore.Http.HttpResults;
1+
using Microsoft.AspNetCore.Http.HttpResults;
32
using ECER.Utilities.Hosting;
43
using MediatR;
54
using ECER.Managers.E2ETest.Contract.E2ETestsContacts;
65
using Microsoft.AspNetCore.Mvc;
76
using ECER.Managers.Registry.Contract.Registrants;
87
using ECER.Utilities.Security;
8+
using AutoMapper;
9+
using ECER.Managers.Registry.Contract.Applications;
10+
using Bogus;
911

1012
namespace ECER.Clients.E2ETestData.E2ETests;
1113

1214
public class E2ETestsEndpoints : IRegisterEndpoints
1315
{
14-
public void Register(IEndpointRouteBuilder endpointRouteBuilder)
16+
public void Register(IEndpointRouteBuilder endpointRouteBuilder)
17+
{
18+
endpointRouteBuilder.MapDelete("/api/E2ETests/user/reset", async Task<Results<Ok<string>, BadRequest<ProblemDetails>, NotFound>> (HttpContext ctx, CancellationToken ct, IMediator messageBus) =>
1519
{
20+
if (!ctx.Request.Headers.TryGetValue("EXTERNAL-USER-ID", out var externalUserId))
21+
{
22+
return TypedResults.BadRequest(new ProblemDetails { Title = "Missing header: EXTERNAL-USER-ID" });
23+
}
1624

17-
endpointRouteBuilder.MapDelete("/api/E2ETests/user/reset", async Task<Results<Ok<string>, BadRequest<ProblemDetails>, NotFound>> (HttpContext ctx, CancellationToken ct, IMediator messageBus) =>
25+
var userIdentity = new UserIdentity(externalUserId.ToString(), "bcsc"); // Convert StringValues to UserIdentity
26+
var profile = (await messageBus.Send(new SearchRegistrantQuery { ByUserIdentity = userIdentity }, ctx.RequestAborted)).Items.SingleOrDefault();
27+
if (profile == null) return TypedResults.NotFound();
28+
var contact_id = profile.UserId;
29+
30+
var result = await messageBus.Send(new E2ETestsDeleteContactApplicationsCommand(contact_id), ct);
31+
return TypedResults.Ok(result);
32+
})
33+
.WithOpenApi("Handles Deletion of all Applications and certificates of a User for E2E Tests", string.Empty, "E2ETests_delete_contact_applications")
34+
.RequireAuthorization()
35+
.DisableAntiforgery()
36+
.WithParameterValidation();
37+
38+
endpointRouteBuilder.MapPost("/api/E2ETests/applications/seed/renewal", async Task<Results<Ok<string>, BadRequest<ProblemDetails>, NotFound>> (HttpContext ctx, CancellationToken ct, IMediator messageBus, IMapper mapper) =>
39+
{
40+
if (!ctx.Request.Headers.TryGetValue("EXTERNAL-USER-ID", out var externalUserId))
41+
{
42+
return TypedResults.BadRequest(new ProblemDetails { Title = "Missing header: EXTERNAL-USER-ID" });
43+
}
44+
45+
if (!ctx.Request.Headers.TryGetValue("APPLICATION-TYPE", out var applicationType))
46+
{
47+
return TypedResults.BadRequest(new ProblemDetails { Title = "Missing header: APPLICATION-TYPE" });
48+
}
49+
50+
CertificationType certificationType;
51+
switch (applicationType.ToString())
52+
{
53+
case "Assistant":
54+
certificationType = CertificationType.EceAssistant;
55+
break;
56+
57+
case "OneYear":
58+
certificationType = CertificationType.OneYear;
59+
break;
60+
61+
case "5Years":
62+
certificationType = CertificationType.FiveYears;
63+
break;
64+
65+
default:
66+
return TypedResults.BadRequest(new ProblemDetails { Title = "Invalid header: APPLICATION-TYPE." });
67+
}
68+
69+
var userIdentity = new UserIdentity(externalUserId.ToString(), "bcsc"); // Convert StringValues to UserIdentity
70+
var profile = (await messageBus.Send(new SearchRegistrantQuery { ByUserIdentity = userIdentity }, ctx.RequestAborted)).Items.SingleOrDefault();
71+
if (profile == null) return TypedResults.NotFound();
72+
var contact_id = profile.UserId;
73+
74+
var draftApplicationObj = new Faker<Application>("en_CA")
75+
.RuleFor(f => f.CertificationTypes, f => f.Make(1, () => certificationType))
76+
.RuleFor(f => f.SignedDate, f => f.Date.Recent())
77+
.RuleFor(f => f.Transcripts, f => f.Make(f.Random.Number(2, 5), () => CreateTranscript()))
78+
.RuleFor(f => f.CharacterReferences, f => f.Make(1, () => CreateCharacterReference()))
79+
.RuleFor(f => f.WorkExperienceReferences, f => f.Make(f.Random.Number(2, 5), () => CreateWorkExperienceReference()))
80+
.Generate();
81+
82+
var application = await messageBus.Send(new SaveDraftApplicationCommand(draftApplicationObj), ct);
83+
84+
var cmd = new SubmitApplicationCommand(application!.Id!, contact_id!);
85+
var submitAppResult = await messageBus.Send(cmd, ct);
86+
87+
if (!submitAppResult.IsSuccess && submitAppResult.Error == SubmissionError.DraftApplicationNotFound)
88+
{
89+
return TypedResults.NotFound();
90+
}
91+
if (!submitAppResult.IsSuccess && submitAppResult.Error == SubmissionError.DraftApplicationValidationFailed)
92+
{
93+
var problemDetails = new ProblemDetails
1894
{
95+
Status = StatusCodes.Status400BadRequest,
96+
Title = "Application submission failed",
97+
Extensions = { ["errors"] = submitAppResult.ValidationErrors }
98+
};
99+
return TypedResults.BadRequest(problemDetails);
100+
}
101+
var result = await messageBus.Send(new E2ETestsGenerateCertificateCommand(submitAppResult.Application!.Id!), ct);
102+
return TypedResults.Ok(result);
103+
})
104+
.WithOpenApi("Handles seeding of Applications and certifications for Renewal workflow", string.Empty, "E2ETests_seed_post_application_certificate")
105+
.RequireAuthorization()
106+
.DisableAntiforgery()
107+
.WithParameterValidation();
108+
}
19109

20-
if (!ctx.Request.Headers.TryGetValue("EXTERNAL-USER-ID", out var externalUserId))
21-
{
22-
return TypedResults.BadRequest(new ProblemDetails { Title = "Missing header: EXTERNAL-USER-ID" });
23-
}
24-
25-
26-
var userIdentity = new UserIdentity (externalUserId.ToString(), "bcsc"); // Convert StringValues to UserIdentity
27-
var profile = (await messageBus.Send(new SearchRegistrantQuery { ByUserIdentity = userIdentity }, ctx.RequestAborted)).Items.SingleOrDefault();
28-
if (profile == null) return TypedResults.NotFound();
29-
var contact_id = profile.UserId;
30-
31-
var result = await messageBus.Send(new E2ETestsDeleteContactApplicationsCommand(contact_id), ct);
32-
return TypedResults.Ok(result);
33-
})
34-
.WithOpenApi("Handles Deletion of all Applications and certificates of a User for E2E Tests", string.Empty, "E2ETests_delete_contact_applications")
35-
.RequireAuthorization()
36-
.DisableAntiforgery()
37-
.WithParameterValidation();
38-
}
110+
private static Transcript CreateTranscript()
111+
{
112+
// Use Faker to generate values for the required parameters
113+
var faker = new Faker("en_CA");
114+
var educationalInstitutionName = faker.Company.CompanyName();
115+
var programName = $"{faker.Hacker.Adjective()} Program";
116+
var studentNumber = faker.Random.Number(10000000, 99999999).ToString();
117+
var studentLastName = faker.Name.LastName();
118+
var startDate = faker.Date.Past();
119+
var endDate = faker.Date.Past();
120+
var isECEAssistant = faker.Random.Bool();
121+
var studentFirstName = faker.Name.FirstName();
122+
var isNameUnverified = faker.Random.Bool();
123+
var educationRecognition = EducationRecognition.Recognized; // Initialize as needed
124+
var educationOrigin = EducationOrigin.InsideBC; // Initialize as needed
125+
126+
// Instantiate the Transcript record with the required arguments
127+
var transcript = new Transcript(
128+
null,
129+
educationalInstitutionName,
130+
programName,
131+
studentNumber,
132+
startDate,
133+
endDate,
134+
isECEAssistant,
135+
studentFirstName,
136+
studentLastName,
137+
isNameUnverified,
138+
educationRecognition,
139+
educationOrigin
140+
)
141+
{
142+
// Populate optional properties
143+
CampusLocation = faker.Address.City(),
144+
TranscriptStatusOption = TranscriptStatusOptions.OfficialTranscriptRequested,
145+
};
146+
147+
return transcript;
148+
}
149+
150+
private CharacterReference CreateCharacterReference()
151+
{
152+
var faker = new Faker("en_CA");
153+
return new CharacterReference(
154+
faker.Name.FirstName(), faker.Name.LastName(), faker.Phone.PhoneNumber(), "[email protected]"
155+
)
156+
{ Status = CharacterReferenceStage.Draft };
157+
}
158+
159+
private WorkExperienceReference CreateWorkExperienceReference()
160+
{
161+
var faker = new Faker("en_CA");
162+
return new WorkExperienceReference(
163+
faker.Name.FirstName(), faker.Name.LastName(), "[email protected]", faker.Random.Number(10, 150)
164+
)
165+
{
166+
PhoneNumber = faker.Phone.PhoneNumber()
167+
};
168+
}
39169
}

src/ECER.Clients.E2ETestData/ECER.Clients.E2ETestData.csproj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
</PropertyGroup>
99

1010
<ItemGroup>
11+
<PackageReference Include="Bogus" />
1112
<PackageReference Include="MinimalApis.Extensions" />
1213
<PackageReference Include="Swashbuckle.AspNetCore" />
1314
</ItemGroup>
@@ -18,6 +19,7 @@
1819
<ProjectReference Include="..\ECER.Managers.Registry.Contract\ECER.Managers.Registry.Contract.csproj" />
1920
<ProjectReference Include="..\ECER.Managers.Registry\ECER.Managers.Registry.csproj" />
2021
<ProjectReference Include="..\ECER.Utilities.Hosting\ECER.Utilities.Hosting.csproj" />
21-
</ItemGroup>
22+
23+
</ItemGroup>
2224

2325
</Project>

src/ECER.Clients.RegistryPortal/ecer.clients.registryportal.client/cypress.config.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,10 @@ export default defineConfig({
1818
],
1919
},
2020
defaultCommandTimeout: 20000,
21+
scrollBehavior: "center", // or 'nearest'
2122
retries: {
2223
runMode: 1, // retry once when we do `cypress run`
2324
openMode: 0, // no retries when we’re developing with `cypress open`
2425
},
25-
env: {
26-
BCSC_USERNAME: env.BCSC_USERNAME,
27-
BCSC_PASSWORD: env.BCSC_PASSWORD,
28-
},
26+
env: { BCSC_USERNAME: env.BCSC_USERNAME, BCSC_PASSWORD: env.BCSC_PASSWORD },
2927
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import selectors from "../../../../support/selectors";
2+
const provinceName = "Alberta";
3+
const certificationName = "Early Childhood Educator Level 1";
4+
5+
describe("Labour Mobility - ECE Level 1 Certification Transfer Application for Alberta", () => {
6+
it("should sucessfully create a ECE Level 1 LM Certification Transfer Application for Alberta", () => {
7+
/** Dashboard */
8+
cy.get(selectors.dashboard.transferButton).click();
9+
10+
/** Transfer Eligibility */
11+
cy.contains("Check your transfer eligibility").should("be.visible");
12+
13+
/** Alberta*/
14+
cy.get(selectors.transferEligibility.provinceDropDownList).should("exist").click({ force: true });
15+
cy.get(selectors.elementType.vListItem).contains(provinceName).click();
16+
17+
/**Out of province Certification Type */
18+
cy.get(selectors.transferEligibility.certificationTypeDropDownList).should("exist").click({ force: true });
19+
cy.get(selectors.elementType.vListItem).contains(certificationName).click();
20+
21+
cy.contains("You can apply to transfer your certification to ECE Assistant certification in B.C.").should("be.visible");
22+
23+
/** View Requirements Button */
24+
cy.get(selectors.transferEligibility.viewRequirementsButton).click();
25+
26+
/**Requirements */
27+
cy.contains("Transfer to ECE Assistant certification").should("be.visible");
28+
cy.get(selectors.applicationRequirements.applyNowButton).click();
29+
30+
/** Declaration */
31+
cy.get(selectors.declaration.declarationCheckbox).check({ force: true });
32+
cy.get(selectors.declaration.continueButton).click();
33+
34+
/** Certificate Information */
35+
36+
cy.contains("Certificate information").should("be.visible");
37+
cy.contains("ECE Assistant").should("be.visible");
38+
cy.contains(provinceName).should("be.visible");
39+
cy.contains(certificationName).should("be.visible");
40+
cy.get(selectors.certificateInformation.nameOnCertificateRadio).first().check({ force: true });
41+
cy.get(selectors.applicationWizard.saveAndContinueButton).click();
42+
43+
cy.ECEAssistantWorkflow(provinceName, certificationName);
44+
});
45+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import selectors from "../../../../support/selectors";
2+
const provinceName = "Alberta";
3+
const certificationName = "Early Childhood Educator Level 2";
4+
5+
describe("Labour Mobility - ECE Level 2 Certification Transfer Application for Alberta", () => {
6+
it("should sucessfully create a ECE Level 2 LM Certification Transfer Application for Alberta", () => {
7+
/** Dashboard */
8+
cy.get(selectors.dashboard.transferButton).click();
9+
10+
/** Transfer Eligibility */
11+
cy.contains("Check your transfer eligibility").should("be.visible");
12+
13+
/** Alberta*/
14+
cy.get(selectors.transferEligibility.provinceDropDownList).should("exist").click({ force: true });
15+
cy.get(selectors.elementType.vListItem).contains(provinceName).click();
16+
17+
/**Out of province Certification Type */
18+
cy.get(selectors.transferEligibility.certificationTypeDropDownList).should("exist").click({ force: true });
19+
cy.get(selectors.elementType.vListItem).contains(certificationName).click();
20+
21+
cy.contains("Work experience").should("be.visible");
22+
23+
cy.get(selectors.transferEligibility.programConfirmationRadioNo).check({ force: true });
24+
25+
cy.contains("You can apply to transfer your certification to ECE One Year certification in B.C.").should("be.visible");
26+
27+
/** View Requirements Button */
28+
cy.get(selectors.transferEligibility.viewRequirementsButton).click();
29+
30+
/**Requirements */
31+
cy.contains("Transfer to ECE One Year certification").should("be.visible");
32+
cy.get(selectors.applicationRequirements.applyNowButton).click();
33+
34+
/** Declaration */
35+
cy.get(selectors.declaration.declarationCheckbox).check({ force: true });
36+
cy.get(selectors.declaration.continueButton).click();
37+
38+
/** Certificate Information */
39+
40+
cy.contains("Certificate information").should("be.visible");
41+
cy.contains("ECE One Year").should("be.visible");
42+
cy.contains(provinceName).should("be.visible");
43+
cy.contains(certificationName).should("be.visible");
44+
cy.get(selectors.certificateInformation.nameOnCertificateRadio).first().check({ force: true });
45+
cy.get(selectors.applicationWizard.saveAndContinueButton).click();
46+
47+
cy.ECEOneYearWorkflow(provinceName, certificationName);
48+
});
49+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import selectors from "../../../../support/selectors";
2+
const provinceName = "Alberta";
3+
const certificationName = "Early Childhood Educator Level 3";
4+
5+
describe("Labour Mobility - ECE Level 3 Certification Transfer Application for Alberta", () => {
6+
it("should sucessfully create a ECE Level 3 LM Certification Transfer Application for Alberta", () => {
7+
/** Dashboard */
8+
cy.get(selectors.dashboard.transferButton).click();
9+
10+
/** Transfer Eligibility */
11+
cy.contains("Check your transfer eligibility").should("be.visible");
12+
13+
/** Alberta*/
14+
cy.get(selectors.transferEligibility.provinceDropDownList).should("exist").click({ force: true });
15+
cy.get(selectors.elementType.vListItem).contains(provinceName).click();
16+
17+
/**Out of province Certification Type */
18+
cy.get(selectors.transferEligibility.certificationTypeDropDownList).should("exist").click({ force: true });
19+
cy.get(selectors.elementType.vListItem).contains(certificationName).click();
20+
21+
cy.contains("Work experience").should("be.visible");
22+
23+
cy.get(selectors.transferEligibility.programConfirmationRadioYes).check({ force: true });
24+
25+
cy.contains(
26+
"You can apply to transfer your certification to ECE Five Year certification with Infant and Toddler Educator (ITE) and Special Needs Educator (SNE) in B.C.",
27+
).should("be.visible");
28+
29+
/** View Requirements Button */
30+
cy.get(selectors.transferEligibility.viewRequirementsButton).click();
31+
32+
/**Requirements */
33+
cy.contains("Transfer to ECE Five Year certification").should("be.visible");
34+
cy.get(selectors.applicationRequirements.applyNowButton).click();
35+
36+
/** Declaration */
37+
cy.get(selectors.declaration.declarationCheckbox).check({ force: true });
38+
cy.get(selectors.declaration.continueButton).click();
39+
40+
/** Certificate Information */
41+
42+
cy.contains("Certificate information").should("be.visible");
43+
cy.contains("ECE Five Year and Special Needs Educator (SNE) and Infant and Toddler Educator (ITE)").should("be.visible");
44+
cy.contains(provinceName).should("be.visible");
45+
cy.contains(certificationName).should("be.visible");
46+
cy.get(selectors.certificateInformation.nameOnCertificateRadio).first().check({ force: true });
47+
cy.get(selectors.applicationWizard.saveAndContinueButton).click();
48+
49+
cy.ECEFiveYearWorkflow(provinceName, certificationName);
50+
});
51+
});

0 commit comments

Comments
 (0)