Builds
Renders/u/:identifier/u/:identifier/builds/u/:identifier/builds/new
Build form page Act
Go to new NZAP TEST ID
await buildForm.gotoNew(NZAP_TEST_ID);
Select weapons Weapons “Tenta Brella”, “Splat Brella”
await buildForm.form.selectWeapons("weapons", [
"Tenta Brella",
"Splat Brella",
]);Select gear HEAD “White Headband”
await buildForm.selectGear("HEAD", "White Headband");Select gear CLOTHES “Basic Tee”
await buildForm.selectGear("CLOTHES", "Basic Tee");Select gear SHOES “Blue Lo-Tops”
await buildForm.selectGear("SHOES", "Blue Lo-Tops");Add ability ISM 12
await buildForm.addAbility("ISM", 12);Fill Title with “Test Build”
await buildForm.form.fill("title", "Test Build");Fill Description with “Test Description”
await buildForm.form.fill("description", "Test Description");Check items Modes “TC”
await buildForm.form.checkItems("modes", ["TC"]);Submit
await buildForm.form.submit();
User builds page Assert
change sorting button is visible
await expect(userBuilds.locators.changeSortingButton).toBeVisible();
Act
Build card 0 → firstBuildCard
const firstBuildCard = userBuilds.buildCard(0);
Build card Assert
weapon image “Tenta Brella” is visible
await expect(firstBuildCard.weaponImage("Tenta Brella")).toBeVisible();weapon image “Splat Brella” is visible
await expect(firstBuildCard.weaponImage("Splat Brella")).toBeVisible();mode image “Tower Control” is visible
await expect(firstBuildCard.modeImage("Tower Control")).toBeVisible();mode image “Splat Zones” is not visible
await expect(firstBuildCard.modeImage("Splat Zones")).not.toBeVisible();title contains “Test Build”
await expect(firstBuildCard.title).toContainText("Test Build");
Source
test("adds a build", async ({ page }) => {
await impersonate(page, NZAP_TEST_ID);
const buildForm = new BuildFormPage(page);
await buildForm.gotoNew(NZAP_TEST_ID);
await buildForm.form.selectWeapons("weapons", [
"Tenta Brella",
"Splat Brella",
]);
await buildForm.selectGear("HEAD", "White Headband");
await buildForm.selectGear("CLOTHES", "Basic Tee");
await buildForm.selectGear("SHOES", "Blue Lo-Tops");
await buildForm.addAbility("ISM", 12);
await buildForm.form.fill("title", "Test Build");
await buildForm.form.fill("description", "Test Description");
await buildForm.form.checkItems("modes", ["TC"]);
await buildForm.form.submit();
const userBuilds = new UserBuildsPage(page);
await expect(userBuilds.locators.changeSortingButton).toBeVisible();
const firstBuildCard = userBuilds.buildCard(0);
await expect(firstBuildCard.weaponImage("Tenta Brella")).toBeVisible();
await expect(firstBuildCard.weaponImage("Splat Brella")).toBeVisible();
await expect(firstBuildCard.modeImage("Tower Control")).toBeVisible();
await expect(firstBuildCard.modeImage("Splat Zones")).not.toBeVisible();
await expect(firstBuildCard.title).toContainText("Test Build");
})Renders/u/:identifier/u/:identifier/builds/u/:identifier/builds/new
Arrange
backdating one build makes the updatedAt sort deterministic
Create 2 × build owner Sendou → [olderBuild]
const [olderBuild] = await factories.BuildFactory.createMany(2, {
ownerId: ADMIN_ID,
});Backdate “Build” olderBuild.id updated at subDays(new Date(), 1)
await factories.backdate("Build", olderBuild.id, {
updatedAt: subDays(new Date(), 1),
});
User builds page Act
Open the user builds page Sendou
await userBuilds.goto(ADMIN_ID);
Build id 0 → buildIdBefore
const buildIdBefore = await userBuilds.buildId(0);
Edit build 0 → buildForm
const buildForm = await userBuilds.editBuild(0);
Build form page Act
Check Private
await buildForm.form.check("isPrivate");Submit
await buildForm.form.submit();
User builds page Assert
build cards count is 2
await expect(userBuilds.locators.buildCards).toHaveCount(2);
private indicator is visible
await expect(userBuilds.buildCard(0).privateIndicator).toBeVisible();
Act
Build id 0 → buildIdAfter
const buildIdAfter = await userBuilds.buildId(0);
Assert
buildIdAfter is buildIdBefore
expect(buildIdAfter).toBe(buildIdBefore);
User builds page Act
Open the user builds page Sendou
await userBuilds.goto(ADMIN_ID);
Assert
build cards count is 1
await expect(userBuilds.locators.buildCards).toHaveCount(1);
private indicator count is 0
await expect(userBuilds.buildCard(0).privateIndicator).toHaveCount(0);
Source
test("makes build private", async ({ page, factories }) => {
// backdating one build makes the updatedAt sort deterministic
const [olderBuild] = await factories.BuildFactory.createMany(2, {
ownerId: ADMIN_ID,
});
await factories.backdate("Build", olderBuild.id, {
updatedAt: subDays(new Date(), 1),
});
await impersonate(page);
const userBuilds = new UserBuildsPage(page);
await userBuilds.goto(ADMIN_ID);
const buildIdBefore = await userBuilds.buildId(0);
const buildForm = await userBuilds.editBuild(0);
await buildForm.form.check("isPrivate");
await buildForm.form.submit();
await expect(userBuilds.locators.buildCards).toHaveCount(2);
await expect(userBuilds.buildCard(0).privateIndicator).toBeVisible();
const buildIdAfter = await userBuilds.buildId(0);
expect(buildIdAfter).toBe(buildIdBefore);
await impersonate(page, NZAP_TEST_ID);
await userBuilds.goto(ADMIN_ID);
await expect(userBuilds.locators.buildCards).toHaveCount(1);
await expect(userBuilds.buildCard(0).privateIndicator).toHaveCount(0);
})Renders/builds/builds/:slug
Arrange
Create 3 × build owner Sendou weapon spl ids 40 modes “TC” abilities ABILITIES_WITH_ISM
await factories.BuildFactory.createMany(3, {
ownerId: ADMIN_ID,
weaponSplIds: [40],
modes: ["TC"],
abilities: ABILITIES_WITH_ISM,
});Create 2 × build owner Sendou weapon spl ids 40 modes “SZ” abilities ABILITIES_WITHOUT_ISM
await factories.BuildFactory.createMany(2, {
ownerId: ADMIN_ID,
weaponSplIds: [40],
modes: ["SZ"],
abilities: ABILITIES_WITHOUT_ISM,
});
Builds page Act
Open weapon 40
await new BuildsPage(page).openWeapon(40);
Weapon builds page Act
Expand build stacks
await weaponBuilds.expandBuildStacks();
Click ability toggle “Ink Saver (Main)”
await weaponBuilds.abilityToggle("Ink Saver (Main)").click();
Assert
build cards count is 3
await expect(weaponBuilds.locators.buildCards).toHaveCount(3);
Act
Select “HAS_NOT” in ability filter type select
await weaponBuilds.locators.abilityFilterTypeSelect.selectOption("HAS_NOT");
Assert
build cards count is 2
await expect(weaponBuilds.locators.buildCards).toHaveCount(2);
Act
Select “AT_LEAST” in ability filter type select
await weaponBuilds.locators.abilityFilterTypeSelect.selectOption(
"AT_LEAST",
);
Assert
build cards count is 3
await expect(weaponBuilds.locators.buildCards).toHaveCount(3);
Act
Select “AT_MOST” in ability filter type select
await weaponBuilds.locators.abilityFilterTypeSelect.selectOption("AT_MOST");
Assert
build cards count is 2
await expect(weaponBuilds.locators.buildCards).toHaveCount(2);
Act
Select “19” in ability filter ap select
await weaponBuilds.locators.abilityFilterApSelect.selectOption("19");
Assert
build cards count is 5
await expect(weaponBuilds.locators.buildCards).toHaveCount(5);
Act
Click ability toggle “Ink Saver (Main)”
await weaponBuilds.abilityToggle("Ink Saver (Main)").click();
Assert
build cards count is 5
await expect(weaponBuilds.locators.buildCards).toHaveCount(5);
Act
Click filter option “Tower Control”
await weaponBuilds.filterOption("Tower Control").click();
Assert
mode badge “TC” count is 3
await expect(weaponBuilds.modeBadge("TC")).toHaveCount(3);
Act
Click filter option “Any mode”
await weaponBuilds.filterOption("Any mode").click();
Assert
build cards count is 5
await expect(weaponBuilds.locators.buildCards).toHaveCount(5);
Act
Click filter option new RegExp(`^Patch ${RECENT_PATCHES[0].patch}`)
await weaponBuilds
.filterOption(new RegExp(`^Patch ${RECENT_PATCHES[0].patch}`))
.click();
Assert
no change in count since all builds in test data are new
build cards count is 5
await expect(weaponBuilds.locators.buildCards).toHaveCount(5);
Source
test("filters builds", async ({ page, factories }) => {
await factories.BuildFactory.createMany(3, {
ownerId: ADMIN_ID,
weaponSplIds: [40],
modes: ["TC"],
abilities: ABILITIES_WITH_ISM,
});
await factories.BuildFactory.createMany(2, {
ownerId: ADMIN_ID,
weaponSplIds: [40],
modes: ["SZ"],
abilities: ABILITIES_WITHOUT_ISM,
});
await impersonate(page, NZAP_TEST_ID);
const weaponBuilds = new WeaponBuildsPage(page);
await new BuildsPage(page).openWeapon(40);
await weaponBuilds.expandBuildStacks();
await weaponBuilds.abilityToggle("Ink Saver (Main)").click();
await expect(weaponBuilds.locators.buildCards).toHaveCount(3);
await weaponBuilds.locators.abilityFilterTypeSelect.selectOption("HAS_NOT");
await expect(weaponBuilds.locators.buildCards).toHaveCount(2);
await weaponBuilds.locators.abilityFilterTypeSelect.selectOption(
"AT_LEAST",
);
await expect(weaponBuilds.locators.buildCards).toHaveCount(3);
await weaponBuilds.locators.abilityFilterTypeSelect.selectOption("AT_MOST");
await expect(weaponBuilds.locators.buildCards).toHaveCount(2);
await weaponBuilds.locators.abilityFilterApSelect.selectOption("19");
await expect(weaponBuilds.locators.buildCards).toHaveCount(5);
await weaponBuilds.abilityToggle("Ink Saver (Main)").click();
await expect(weaponBuilds.locators.buildCards).toHaveCount(5);
await weaponBuilds.filterOption("Tower Control").click();
await expect(weaponBuilds.modeBadge("TC")).toHaveCount(3);
await weaponBuilds.filterOption("Any mode").click();
await expect(weaponBuilds.locators.buildCards).toHaveCount(5);
await weaponBuilds
.filterOption(new RegExp(`^Patch ${RECENT_PATCHES[0].patch}`))
.click();
// no change in count since all builds in test data are new
await expect(weaponBuilds.locators.buildCards).toHaveCount(5);
})Arrange
Create 3 × build owner Sendou weapon spl ids 40 abilities ABILITIES_WITH_ISM
await factories.BuildFactory.createMany(3, {
ownerId: ADMIN_ID,
weaponSplIds: [40],
abilities: ABILITIES_WITH_ISM,
});Create 2 × build owner Sendou weapon spl ids 0 abilities ABILITIES_WITHOUT_ISM
await factories.BuildFactory.createMany(2, {
ownerId: ADMIN_ID,
weaponSplIds: [0],
abilities: ABILITIES_WITHOUT_ISM,
});
User builds page Act
Open the user builds page Sendou
await userBuilds.goto(ADMIN_ID);
Assert
build cards count is 5
await expect(userBuilds.locators.buildCards).toHaveCount(5);
Act
Click filter option /^Sploosh-o-matic/
await userBuilds.filterOption(/^Sploosh-o-matic/).click();
Assert
build cards count is 2
await expect(userBuilds.locators.buildCards).toHaveCount(2);
Act
Click filter option /^Any weapon/
await userBuilds.filterOption(/^Any weapon/).click();
Click ability toggle “Ink Saver (Main)”
await userBuilds.abilityToggle("Ink Saver (Main)").click();
Assert
build cards count is 3
await expect(userBuilds.locators.buildCards).toHaveCount(3);
Source
test("filters a user's builds", async ({ page, factories }) => {
await factories.BuildFactory.createMany(3, {
ownerId: ADMIN_ID,
weaponSplIds: [40],
abilities: ABILITIES_WITH_ISM,
});
await factories.BuildFactory.createMany(2, {
ownerId: ADMIN_ID,
weaponSplIds: [0],
abilities: ABILITIES_WITHOUT_ISM,
});
await impersonate(page, NZAP_TEST_ID);
const userBuilds = new UserBuildsPage(page);
await userBuilds.goto(ADMIN_ID);
await expect(userBuilds.locators.buildCards).toHaveCount(5);
await userBuilds.filterOption(/^Sploosh-o-matic/).click();
await expect(userBuilds.locators.buildCards).toHaveCount(2);
await userBuilds.filterOption(/^Any weapon/).click();
await userBuilds.abilityToggle("Ink Saver (Main)").click();
await expect(userBuilds.locators.buildCards).toHaveCount(3);
})paginates a user's builds
Arrange
Create BUILDS_PAGE_SIZE + 1 × build owner Sendou
await factories.BuildFactory.createMany(BUILDS_PAGE_SIZE + 1, {
ownerId: ADMIN_ID,
});
User builds page Act
Open the user builds page Sendou
await userBuilds.goto(ADMIN_ID);
Assert
build cards count is BUILDS_PAGE_SIZE
await expect(userBuilds.locators.buildCards).toHaveCount(BUILDS_PAGE_SIZE);
Act
Click next page button
await userBuilds.locators.nextPageButton.click();
Assert
build cards count is 1
await expect(userBuilds.locators.buildCards).toHaveCount(1);
Source
test("paginates a user's builds", async ({ page, factories }) => {
await factories.BuildFactory.createMany(BUILDS_PAGE_SIZE + 1, {
ownerId: ADMIN_ID,
});
const userBuilds = new UserBuildsPage(page);
await userBuilds.goto(ADMIN_ID);
await expect(userBuilds.locators.buildCards).toHaveCount(BUILDS_PAGE_SIZE);
await userBuilds.locators.nextPageButton.click();
await expect(userBuilds.locators.buildCards).toHaveCount(1);
})stacks an author's builds and expands the stack
Arrange
Create 3 × build owner Sendou weapon spl ids 40
await factories.BuildFactory.createMany(3, {
ownerId: ADMIN_ID,
weaponSplIds: [40],
});Create build owner N-ZAP weapon spl ids 40
await factories.BuildFactory.create({
ownerId: NZAP_TEST_ID,
weaponSplIds: [40],
});
Builds page Act
Open weapon 40
await new BuildsPage(page).openWeapon(40);
Weapon builds page Assert
build cards count is 2
await expect(weaponBuilds.locators.buildCards).toHaveCount(2);
expand stack buttons have accessible name “2 more builds”
await expect(weaponBuilds.locators.expandStackButtons).toHaveAccessibleName(
"2 more builds",
);
Act
Click expand stack buttons
await weaponBuilds.locators.expandStackButtons.click();
Assert
build cards count is 4
await expect(weaponBuilds.locators.buildCards).toHaveCount(4);
Act
Click collapse stack buttons
await weaponBuilds.locators.collapseStackButtons.click();
Assert
build cards count is 2
await expect(weaponBuilds.locators.buildCards).toHaveCount(2);
Source
test("stacks an author's builds and expands the stack", async ({
page,
factories,
}) => {
await factories.BuildFactory.createMany(3, {
ownerId: ADMIN_ID,
weaponSplIds: [40],
});
await factories.BuildFactory.create({
ownerId: NZAP_TEST_ID,
weaponSplIds: [40],
});
const weaponBuilds = new WeaponBuildsPage(page);
await new BuildsPage(page).openWeapon(40);
await expect(weaponBuilds.locators.buildCards).toHaveCount(2);
await expect(weaponBuilds.locators.expandStackButtons).toHaveAccessibleName(
"2 more builds",
);
await weaponBuilds.locators.expandStackButtons.click();
await expect(weaponBuilds.locators.buildCards).toHaveCount(4);
await weaponBuilds.locators.collapseStackButtons.click();
await expect(weaponBuilds.locators.buildCards).toHaveCount(2);
})aggregates builds into ability stats and popular builds
Renders/builds/builds/:slug/builds/:slug/popular/builds/:slug/stats
Arrange
Create 3 × build owner Sendou weapon spl ids 40 abilities STATS_ABILITIES
await factories.BuildFactory.createMany(3, {
ownerId: ADMIN_ID,
weaponSplIds: [40],
abilities: STATS_ABILITIES,
});Create build owner N-ZAP weapon spl ids 40 abilities STATS_ABILITIES
await factories.BuildFactory.create({
ownerId: NZAP_TEST_ID,
weaponSplIds: [40],
abilities: STATS_ABILITIES,
});a build for another weapon so site-wide stats differ from the weapon's
Create build owner N-ZAP weapon spl ids 10 abilities OTHER_WEAPON_ABILITIES
await factories.BuildFactory.create({
ownerId: NZAP_TEST_ID,
weaponSplIds: [10],
abilities: OTHER_WEAPON_ABILITIES,
});
Builds page Act
Open weapon 40
await new BuildsPage(page).openWeapon(40);
Weapon builds page Act
Expand build stacks
await weaponBuilds.expandBuildStacks();
Assert
build cards count is 4
await expect(weaponBuilds.locators.buildCards).toHaveCount(4);
Act
Click ability stats tab
await weaponBuilds.locators.abilityStatsTab.click();
Build stats page Assert
builds count 4 is visible
await expect(buildStats.buildsCount(4)).toBeVisible();
SSU and RSU weapon averages
ap average 19 count is 2
await expect(buildStats.apAverage(19)).toHaveCount(2);
ap average 9 count is 1
await expect(buildStats.apAverage(9)).toHaveCount(1);
CB is in every Splattershot build but in 4 of the 5 builds site-wide
main only ability percentages ability name “Comeback” weapon percentage 100 all percentage 80 is visible
await expect(
buildStats.mainOnlyAbilityPercentages({
abilityName: "Comeback",
weaponPercentage: 100,
allPercentage: 80,
}),
).toBeVisible();
Popular builds page Act
Open the popular builds page “splattershot”
await popularBuilds.goto("splattershot");
Assert
admin's identical builds count once, N-ZAP's brings it to 2 players
placement 1 is visible
await expect(popularBuilds.placement(1)).toBeVisible();
players count 2 is visible
await expect(popularBuilds.playersCount(2)).toBeVisible();
build ability rank 1 ability “CB” count is 1
await expect(
popularBuilds.buildAbility({ rank: 1, ability: "CB" }),
).toHaveCount(1);19 AP = one main and three subs
build ability rank 1 ability “SSU” count is 4
await expect(
popularBuilds.buildAbility({ rank: 1, ability: "SSU" }),
).toHaveCount(4);build ability rank 1 ability “RSU” count is 4
await expect(
popularBuilds.buildAbility({ rank: 1, ability: "RSU" }),
).toHaveCount(4);build ability rank 1 ability “ISM” count is 3
await expect(
popularBuilds.buildAbility({ rank: 1, ability: "ISM" }),
).toHaveCount(3);placement 2 is not visible
await isNotVisible(popularBuilds.placement(2));
Source
test("aggregates builds into ability stats and popular builds", async ({
page,
factories,
}) => {
await factories.BuildFactory.createMany(3, {
ownerId: ADMIN_ID,
weaponSplIds: [40],
abilities: STATS_ABILITIES,
});
await factories.BuildFactory.create({
ownerId: NZAP_TEST_ID,
weaponSplIds: [40],
abilities: STATS_ABILITIES,
});
// a build for another weapon so site-wide stats differ from the weapon's
await factories.BuildFactory.create({
ownerId: NZAP_TEST_ID,
weaponSplIds: [10],
abilities: OTHER_WEAPON_ABILITIES,
});
const weaponBuilds = new WeaponBuildsPage(page);
await new BuildsPage(page).openWeapon(40);
await weaponBuilds.expandBuildStacks();
await expect(weaponBuilds.locators.buildCards).toHaveCount(4);
await weaponBuilds.locators.abilityStatsTab.click();
const buildStats = new BuildStatsPage(page);
await expect(buildStats.buildsCount(4)).toBeVisible();
// SSU and RSU weapon averages
await expect(buildStats.apAverage(19)).toHaveCount(2);
// ISM weapon average
await expect(buildStats.apAverage(9)).toHaveCount(1);
// CB is in every Splattershot build but in 4 of the 5 builds site-wide
await expect(
buildStats.mainOnlyAbilityPercentages({
abilityName: "Comeback",
weaponPercentage: 100,
allPercentage: 80,
}),
).toBeVisible();
const popularBuilds = new PopularBuildsPage(page);
await popularBuilds.goto("splattershot");
// admin's identical builds count once, N-ZAP's brings it to 2 players
await expect(popularBuilds.placement(1)).toBeVisible();
await expect(popularBuilds.playersCount(2)).toBeVisible();
await expect(
popularBuilds.buildAbility({ rank: 1, ability: "CB" }),
).toHaveCount(1);
// 19 AP = one main and three subs
await expect(
popularBuilds.buildAbility({ rank: 1, ability: "SSU" }),
).toHaveCount(4);
await expect(
popularBuilds.buildAbility({ rank: 1, ability: "RSU" }),
).toHaveCount(4);
await expect(
popularBuilds.buildAbility({ rank: 1, ability: "ISM" }),
).toHaveCount(3);
await isNotVisible(popularBuilds.placement(2));
})edits build title, changes sorting and deletes a build
Renders/u/:identifier/u/:identifier/builds/u/:identifier/builds/new
Arrange
Create build owner Sendou title “Alpha Build” → olderBuild
const olderBuild = await factories.BuildFactory.create({
ownerId: ADMIN_ID,
title: "Alpha Build",
});Create build owner Sendou title “Mid Build”
await factories.BuildFactory.create({
ownerId: ADMIN_ID,
title: "Mid Build",
});Backdate “Build” olderBuild.id updated at subDays(new Date(), 1)
await factories.backdate("Build", olderBuild.id, {
updatedAt: subDays(new Date(), 1),
});
User builds page Act
Open the user builds page Sendou
await userBuilds.goto(ADMIN_ID);
Assert
title contains “Mid Build”
await expect(userBuilds.buildCard(0).title).toContainText("Mid Build");
Act
Edit build 0 → buildForm
const buildForm = await userBuilds.editBuild(0);
Build form page Act
Fill Title with “Zulu Build”
await buildForm.form.fill("title", "Zulu Build");Submit
await buildForm.form.submit();
User builds page Assert
title contains “Zulu Build”
await expect(userBuilds.buildCard(0).title).toContainText("Zulu Build");title contains “Alpha Build”
await expect(userBuilds.buildCard(1).title).toContainText("Alpha Build");
Act
Change sorting to “ALPHABETICAL_TITLE”
await userBuilds.changeSortingTo("ALPHABETICAL_TITLE");
Assert
title contains “Alpha Build”
await expect(userBuilds.buildCard(0).title).toContainText("Alpha Build");title contains “Zulu Build”
await expect(userBuilds.buildCard(1).title).toContainText("Zulu Build");
Act
Delete build 0
await userBuilds.deleteBuild(0);
Assert
build cards count is 1
await expect(userBuilds.locators.buildCards).toHaveCount(1);
title contains “Zulu Build”
await expect(userBuilds.buildCard(0).title).toContainText("Zulu Build");
Source
test("edits build title, changes sorting and deletes a build", async ({
page,
factories,
}) => {
const olderBuild = await factories.BuildFactory.create({
ownerId: ADMIN_ID,
title: "Alpha Build",
});
await factories.BuildFactory.create({
ownerId: ADMIN_ID,
title: "Mid Build",
});
await factories.backdate("Build", olderBuild.id, {
updatedAt: subDays(new Date(), 1),
});
await impersonate(page);
const userBuilds = new UserBuildsPage(page);
await userBuilds.goto(ADMIN_ID);
await expect(userBuilds.buildCard(0).title).toContainText("Mid Build");
const buildForm = await userBuilds.editBuild(0);
await buildForm.form.fill("title", "Zulu Build");
await buildForm.form.submit();
await expect(userBuilds.buildCard(0).title).toContainText("Zulu Build");
await expect(userBuilds.buildCard(1).title).toContainText("Alpha Build");
await userBuilds.changeSortingTo("ALPHABETICAL_TITLE");
await expect(userBuilds.buildCard(0).title).toContainText("Alpha Build");
await expect(userBuilds.buildCard(1).title).toContainText("Zulu Build");
await userBuilds.deleteBuild(0);
await expect(userBuilds.locators.buildCards).toHaveCount(1);
await expect(userBuilds.buildCard(0).title).toContainText("Zulu Build");
})newBuildBaseSchema.weaponsapp/features/user-page/user-page-schemas.ts:261
weapons: weaponPool({
label: "labels.buildWeapons",
minCount: 1,
maxCount: 5,
disableSorting: true,
disableFavorites: true,
disableAltSkinDuplicates: true,
})newBuildBaseSchema.titleapp/features/user-page/user-page-schemas.ts:282
title: textField({
label: "labels.buildTitle",
maxLength: 50,
})newBuildBaseSchema.descriptionapp/features/user-page/user-page-schemas.ts:286
description: textAreaOptional({
label: "labels.description",
maxLength: 280,
})newBuildBaseSchema.modesapp/features/user-page/user-page-schemas.ts:290
modes: checkboxGroup({
label: "labels.buildModes",
items: modeItems,
})UserBuildsPage.locators.changeSortingButtone2e/pages/builds/user-builds-page.ts:23
No JSDoc
page.getByTestId("change-sorting-button")UserBuildsPage.buildCarde2e/pages/builds/user-builds-page.ts:35
No JSDoc
buildCard(nth: number) {
return new BuildCard(this.locators.buildCards.nth(nth));
}BuildCard.weaponImagee2e/pages/builds/build-card.ts:18
No JSDoc
weaponImage(weaponName: string) {
return this.root.getByAltText(weaponName);
}BuildCard.modeImagee2e/pages/builds/build-card.ts:22
No JSDoc
modeImage(modeName: string) {
return this.root.getByAltText(modeName);
}BuildCard.titlee2e/pages/builds/build-card.ts:10
No JSDoc
get title() {
return this.root.getByTestId("build-title");
}BuildFormPagee2e/pages/builds/build-form-page.ts:8
No JSDoc
UserBuildsPagee2e/pages/builds/user-builds-page.ts:16
No JSDoc
BuildCarde2e/pages/builds/build-card.ts:3
No JSDoc
UserBuildsPage.gotoe2e/pages/builds/user-builds-page.ts:31
No JSDoc
async goto(userId: number) {
await navigate({ page: this.page, url: userBuildsPage({ id: userId }) });
}UserBuildsPage.buildIde2e/pages/builds/user-builds-page.ts:47
No JSDoc
async buildId(nth: number) {
const href = await this.locators.editBuildLinks
.nth(nth)
.getAttribute("href");
invariant(href, "edit-build link missing href");
const match = href.match(/buildId=(\d+)/);
invariant(match, `buildId not found in href: ${href}`);
return Number(match[1]);
}UserBuildsPage.editBuilde2e/pages/builds/user-builds-page.ts:57
No JSDoc
async editBuild(nth: number) {
await this.locators.editBuildLinks.nth(nth).click();
return new BuildFormPage(this.page);
}newBuildBaseSchema.isPrivateapp/features/user-page/user-page-schemas.ts:294
isPrivate: toggle({
label: "labels.buildPrivate",
bottomText: "bottomTexts.buildPrivate",
})UserBuildsPage.locators.buildCardse2e/pages/builds/user-builds-page.ts:24
No JSDoc
page.getByTestId("build-card")BuildsPage.openWeapone2e/pages/builds/builds-page.ts:25
No JSDoc
async openWeapon(weaponSplId: MainWeaponId) {
await this.goto();
await this.weaponLink(weaponSplId).click();
}WeaponBuildsPage.expandBuildStackse2e/pages/builds/weapon-builds-page.ts:32
No JSDoc
async expandBuildStacks() {
const buttons = this.locators.expandStackButtons;
await expect(this.locators.buildCards.first()).toBeVisible();
for (let count = await buttons.count(); count > 0; count--) {
await buttons.first().click();
await expect(buttons).toHaveCount(count - 1);
}
}WeaponBuildsPage.abilityTogglee2e/pages/builds/weapon-builds-page.ts:50
No JSDoc
abilityToggle(abilityName: string) {
return this.page.getByRole("button", { name: abilityName, exact: true });
}WeaponBuildsPage.locators.buildCardse2e/pages/builds/weapon-builds-page.ts:14
No JSDoc
page.getByTestId("build-card")WeaponBuildsPage.locators.abilityFilterTypeSelecte2e/pages/builds/weapon-builds-page.ts:19
No JSDoc
page.getByTestId("ability-filter-type-select")WeaponBuildsPage.locators.abilityFilterApSelecte2e/pages/builds/weapon-builds-page.ts:20
No JSDoc
page.getByTestId("ability-filter-ap-select")WeaponBuildsPage.filterOptione2e/pages/builds/weapon-builds-page.ts:54
No JSDoc
filterOption(name: string | RegExp) {
return this.page.getByRole("radio", { name, exact: true });
}WeaponBuildsPage.modeBadgee2e/pages/builds/weapon-builds-page.ts:46
No JSDoc
modeBadge(mode: ModeShort) {
return this.page.getByTestId(`build-mode-${mode}`);
}BuildsPagee2e/pages/builds/builds-page.ts:6
No JSDoc
WeaponBuildsPagee2e/pages/builds/weapon-builds-page.ts:7
No JSDoc
UserBuildsPage.filterOptione2e/pages/builds/user-builds-page.ts:39
No JSDoc
filterOption(name: string | RegExp) {
return this.page.getByRole("radio", { name, exact: true });
}UserBuildsPage.abilityTogglee2e/pages/builds/user-builds-page.ts:43
No JSDoc
abilityToggle(abilityName: string) {
return this.page.getByRole("button", { name: abilityName, exact: true });
}UserBuildsPage.locators.nextPageButtone2e/pages/builds/user-builds-page.ts:27
No JSDoc
page.getByRole("button", { name: "Next page" })WeaponBuildsPage.locators.expandStackButtonse2e/pages/builds/weapon-builds-page.ts:17
No JSDoc
page.getByTestId("expand-build-stack")WeaponBuildsPage.locators.collapseStackButtonse2e/pages/builds/weapon-builds-page.ts:18
No JSDoc
page.getByTestId("collapse-build-stack")WeaponBuildsPage.locators.abilityStatsTabe2e/pages/builds/weapon-builds-page.ts:15
No JSDoc
page.getByRole("tab", { name: /Ability stats/ })BuildStatsPage.buildsCounte2e/pages/builds/build-stats-page.ts:16
No JSDoc
buildsCount(count: number) {
return this.page.getByText(`Based on ${count} builds`, { exact: true });
}BuildStatsPage.apAveragee2e/pages/builds/build-stats-page.ts:20
No JSDoc
apAverage(ap: number) {
return this.page.getByText(`${ap} AP`, { exact: true });
}BuildStatsPage.mainOnlyAbilityPercentagese2e/pages/builds/build-stats-page.ts:24
No JSDoc
mainOnlyAbilityPercentages({
abilityName,
weaponPercentage,
allPercentage,
}: {
abilityName: string;
weaponPercentage: number;
allPercentage: number;
}) {
return this.page.getByRole("img", {
name: `${abilityName}: ${weaponPercentage}%, all weapons ${allPercentage}%`,
exact: true,
});
}PopularBuildsPage.gotoe2e/pages/builds/popular-builds-page.ts:13
No JSDoc
async goto(weaponSlug: string) {
await navigate({
page: this.page,
url: weaponBuildPopularPage(weaponSlug),
});
}PopularBuildsPage.placemente2e/pages/builds/popular-builds-page.ts:20
No JSDoc
placement(nth: number) {
return this.page.getByText(`#${nth}`, { exact: true });
}PopularBuildsPage.playersCounte2e/pages/builds/popular-builds-page.ts:24
No JSDoc
playersCount(count: number) {
return this.page.getByText(`${count} players`, { exact: true });
}PopularBuildsPage.buildAbilitye2e/pages/builds/popular-builds-page.ts:28
No JSDoc
buildAbility({ rank, ability }: { rank: number; ability: Ability }) {
return this.page
.getByRole("listitem")
.filter({ has: this.placement(rank) })
.getByTestId(`${ability}-ability`);
}isNotVisiblee2e/helpers/playwright.ts:745
No JSDoc
export function isNotVisible(locator: Locator) {
return expect(locator).toHaveCount(0);
}BuildStatsPagee2e/pages/builds/build-stats-page.ts:5
No JSDoc
PopularBuildsPagee2e/pages/builds/popular-builds-page.ts:6
No JSDoc
UserBuildsPage.changeSortingToe2e/pages/builds/user-builds-page.ts:63
async changeSortingTo(sort: BuildSort) {
await this.locators.changeSortingButton.click();
const dialog = this.page.getByRole("dialog");
for (const _ of DEFAULT_BUILD_SORT) {
await dialog.getByTestId("remove-sorting-button").first().click();
}
await dialog.getByTestId(`add-sorting-${sort}`).click();
await submit(this.page);
}UserBuildsPage.deleteBuilde2e/pages/builds/user-builds-page.ts:75
No JSDoc
async deleteBuild(nth: number) {
await this.locators.deleteBuildButtons.nth(nth).click();
await modalClickConfirmButton(this.page);
}