Composition Analyzer
weapon selection, removal, and URL persistence
Renders/comp-analyzer
Comp analyzer page Act
Open the comp analyzer page
await compAnalyzer.goto();
Assert
selected weapons is visible
await expect(compAnalyzer.locators.selectedWeapons).toBeVisible();
empty weapon slots count is 4
await expect(compAnalyzer.locators.emptyWeaponSlots).toHaveCount(4);
Act
Select weapon 40
await compAnalyzer.selectWeapon(40);
Assert
selected weapon 0 is visible
await expect(compAnalyzer.selectedWeapon(0)).toBeVisible();
empty weapon slots count is 3
await expect(compAnalyzer.locators.emptyWeaponSlots).toHaveCount(3);
Act
Remove weapon 0
await compAnalyzer.removeWeapon(0);
Assert
empty weapon slots count is 4
await expect(compAnalyzer.locators.emptyWeaponSlots).toHaveCount(4);
a full four weapons auto-collapse the grid
categorization toggle is visible
await expect(compAnalyzer.locators.categorizationToggle).toBeVisible();
Act
Select weapon 40
await compAnalyzer.selectWeapon(40);
Select weapon 50
await compAnalyzer.selectWeapon(50);
Select weapon 60
await compAnalyzer.selectWeapon(60);
Select weapon 70
await compAnalyzer.selectWeapon(70);
Assert
categorization toggle is not visible
await expect(compAnalyzer.locators.categorizationToggle).not.toBeVisible();
the page URL is /weapons=/
await expect(page).toHaveURL(/weapons=/);
Act
Reload the page
await page.reload();
Assert
selected weapon 0 is visible
await expect(compAnalyzer.selectedWeapon(0)).toBeVisible();
selected weapon 1 is visible
await expect(compAnalyzer.selectedWeapon(1)).toBeVisible();
selected weapon 2 is visible
await expect(compAnalyzer.selectedWeapon(2)).toBeVisible();
selected weapon 3 is visible
await expect(compAnalyzer.selectedWeapon(3)).toBeVisible();
Source
test("weapon selection, removal, and URL persistence", async ({ page }) => {
const compAnalyzer = new CompAnalyzerPage(page);
await compAnalyzer.goto();
await expect(compAnalyzer.locators.selectedWeapons).toBeVisible();
await expect(compAnalyzer.locators.emptyWeaponSlots).toHaveCount(4);
await compAnalyzer.selectWeapon(40);
await expect(compAnalyzer.selectedWeapon(0)).toBeVisible();
await expect(compAnalyzer.locators.emptyWeaponSlots).toHaveCount(3);
await compAnalyzer.removeWeapon(0);
await expect(compAnalyzer.locators.emptyWeaponSlots).toHaveCount(4);
// a full four weapons auto-collapse the grid
await expect(compAnalyzer.locators.categorizationToggle).toBeVisible();
await compAnalyzer.selectWeapon(40);
await compAnalyzer.selectWeapon(50);
await compAnalyzer.selectWeapon(60);
await compAnalyzer.selectWeapon(70);
await expect(compAnalyzer.locators.categorizationToggle).not.toBeVisible();
await expect(page).toHaveURL(/weapons=/);
await page.reload();
await expect(compAnalyzer.selectedWeapon(0)).toBeVisible();
await expect(compAnalyzer.selectedWeapon(1)).toBeVisible();
await expect(compAnalyzer.selectedWeapon(2)).toBeVisible();
await expect(compAnalyzer.selectedWeapon(3)).toBeVisible();
})weapon grid controls and categorization
Renders/comp-analyzer
Comp analyzer page Act
Open the comp analyzer page
await compAnalyzer.goto();
Assert
categorization radio “category” is checked
await expect(compAnalyzer.categorizationRadio("category")).toBeChecked();
Act
Select categorization “sub”
await compAnalyzer.selectCategorization("sub");
Assert
categorization radio “sub” is checked
await expect(compAnalyzer.categorizationRadio("sub")).toBeChecked();
Act
Select categorization “special”
await compAnalyzer.selectCategorization("special");
Assert
categorization radio “special” is checked
await expect(compAnalyzer.categorizationRadio("special")).toBeChecked();categorization toggle is visible
await expect(compAnalyzer.locators.categorizationToggle).toBeVisible();
Act
Toggle weapon grid
await compAnalyzer.toggleWeaponGrid();
Assert
categorization toggle is not visible
await expect(compAnalyzer.locators.categorizationToggle).not.toBeVisible();
Act
Toggle weapon grid
await compAnalyzer.toggleWeaponGrid();
Assert
categorization toggle is visible
await expect(compAnalyzer.locators.categorizationToggle).toBeVisible();
Act
Select categorization “sub”
await compAnalyzer.selectCategorization("sub");
Assert
the page URL is /categorization=sub/
await expect(page).toHaveURL(/categorization=sub/);
Act
Reload the page
await page.reload();
Assert
categorization radio “sub” is checked
await expect(compAnalyzer.categorizationRadio("sub")).toBeChecked();
Source
test("weapon grid controls and categorization", async ({ page }) => {
const compAnalyzer = new CompAnalyzerPage(page);
await compAnalyzer.goto();
await expect(compAnalyzer.categorizationRadio("category")).toBeChecked();
await compAnalyzer.selectCategorization("sub");
await expect(compAnalyzer.categorizationRadio("sub")).toBeChecked();
await compAnalyzer.selectCategorization("special");
await expect(compAnalyzer.categorizationRadio("special")).toBeChecked();
await expect(compAnalyzer.locators.categorizationToggle).toBeVisible();
await compAnalyzer.toggleWeaponGrid();
await expect(compAnalyzer.locators.categorizationToggle).not.toBeVisible();
await compAnalyzer.toggleWeaponGrid();
await expect(compAnalyzer.locators.categorizationToggle).toBeVisible();
await compAnalyzer.selectCategorization("sub");
await expect(page).toHaveURL(/categorization=sub/);
await page.reload();
await expect(compAnalyzer.categorizationRadio("sub")).toBeChecked();
})analysis sections appear and can be collapsed
Renders/comp-analyzer
Comp analyzer page Act
Open the comp analyzer page
await compAnalyzer.goto();
Arrange
damageCombos = damage combos
const damageCombos = compAnalyzer.damageCombos;
Assert
damageCombos.root is not visible
await expect(damageCombos.root).not.toBeVisible();
range visualization is not visible
await expect(compAnalyzer.locators.rangeVisualization).not.toBeVisible();
Act
210 is a blaster, which has range data
Select weapon 40
await compAnalyzer.selectWeapon(40);
Select weapon 210
await compAnalyzer.selectWeapon(210);
Assert
damageCombos.root is visible
await expect(damageCombos.root).toBeVisible();
range visualization is visible
await expect(compAnalyzer.locators.rangeVisualization).toBeVisible();
damageCombos.content is visible
await expect(damageCombos.content).toBeVisible();
Act
Toggle collapsed
await damageCombos.toggleCollapsed();
Assert
damageCombos.content is not visible
await expect(damageCombos.content).not.toBeVisible();
Act
Toggle collapsed
await damageCombos.toggleCollapsed();
Assert
damageCombos.content is visible
await expect(damageCombos.content).toBeVisible();
Source
test("analysis sections appear and can be collapsed", async ({ page }) => {
const compAnalyzer = new CompAnalyzerPage(page);
await compAnalyzer.goto();
const damageCombos = compAnalyzer.damageCombos;
await expect(damageCombos.root).not.toBeVisible();
await expect(compAnalyzer.locators.rangeVisualization).not.toBeVisible();
// 210 is a blaster, which has range data
await compAnalyzer.selectWeapon(40);
await compAnalyzer.selectWeapon(210);
await expect(damageCombos.root).toBeVisible();
await expect(compAnalyzer.locators.rangeVisualization).toBeVisible();
await expect(damageCombos.content).toBeVisible();
await damageCombos.toggleCollapsed();
await expect(damageCombos.content).not.toBeVisible();
await damageCombos.toggleCollapsed();
await expect(damageCombos.content).toBeVisible();
})damage combo sliders and filtering work correctly
Renders/comp-analyzer
Comp analyzer page Act
Open the comp analyzer page
await compAnalyzer.goto();
Splattershot Jr. has Splat Bomb sub
Select weapon 10
await compAnalyzer.selectWeapon(10);
Select weapon 40
await compAnalyzer.selectWeapon(40);
Arrange
damageCombos = damage combos
const damageCombos = compAnalyzer.damageCombos;
Assert
damageCombos.root is visible
await expect(damageCombos.root).toBeVisible();
Act
All text contents → initialDamageValues
const initialDamageValues =
await damageCombos.damageValues.allTextContents();
Fill damageCombos.subDefenseSlider with “57”
await damageCombos.subDefenseSlider.fill("57");All text contents → newDamageValues
const newDamageValues = await damageCombos.damageValues.allTextContents();
Assert
initialDamageValues.join(",") does not equal newDamageValues.join(",")
expect(initialDamageValues.join(",")).not.toEqual(
newDamageValues.join(","),
);
Act
Fill damageCombos.subDefenseSlider with “0”
await damageCombos.subDefenseSlider.fill("0");All text contents → initialInkTimes
const initialInkTimes = await damageCombos.inkTimes.allTextContents();
Fill damageCombos.inkResistanceSlider with “57”
await damageCombos.inkResistanceSlider.fill("57");All text contents → newInkTimes
const newInkTimes = await damageCombos.inkTimes.allTextContents();
Assert
ink resistance makes ink times longer or reveals more ink combos
If initialInkTimes.length > 0 || newInkTimes.length > 0
if (initialInkTimes.length > 0 || newInkTimes.length > 0) {
const initialTotalFrames = initialInkTimes.reduce(
(sum, t) => sum + (Number.parseInt(t, 10) || 0),
0,
);
const newTotalFrames = newInkTimes.reduce(
(sum, t) => sum + (Number.parseInt(t, 10) || 0),
0,
);
expect(newTotalFrames).toBeGreaterThanOrEqual(initialTotalFrames);
}initialTotalFrames = initialInkTimes.reduce( (sum, t) => sum + (Number.parseInt(t, 10) || 0), 0, )
const initialTotalFrames = initialInkTimes.reduce(
(sum, t) => sum + (Number.parseInt(t, 10) || 0),
0,
);
newTotalFrames = newInkTimes.reduce( (sum, t) => sum + (Number.parseInt(t, 10) || 0), 0, )
const newTotalFrames = newInkTimes.reduce(
(sum, t) => sum + (Number.parseInt(t, 10) || 0),
0,
);
newTotalFrames be greater than or equal initialTotalFrames
expect(newTotalFrames).toBeGreaterThanOrEqual(initialTotalFrames);
Arrange
firstDamageTypeLabel = damageCombos.damageTypeLabels.first()
const firstDamageTypeLabel = damageCombos.damageTypeLabels.first();
Act
Text content → damageTypeText
const damageTypeText = await firstDamageTypeLabel.textContent();
Assert
damageCombos.filteredItems count is 0
await expect(damageCombos.filteredItems).toHaveCount(0);
Act
Click firstDamageTypeLabel
await firstDamageTypeLabel.click();
Count → filteredCount
const filteredCount = await damageCombos.filteredItems.count();
Assert
filteredCount is more than 0
expect(filteredCount).toBeGreaterThan(0);
damageCombos.filteredItems.first() contains damageTypeText ?? ""
await expect(damageCombos.filteredItems.first()).toContainText(
damageTypeText ?? "",
);
Act
Click damageCombos.filteredItems.first()
await damageCombos.filteredItems.first().click();
Assert
damageCombos.filteredItems count is filteredCount - 1
await expect(damageCombos.filteredItems).toHaveCount(filteredCount - 1);
Source
test("damage combo sliders and filtering work correctly", async ({
page,
}) => {
const compAnalyzer = new CompAnalyzerPage(page);
await compAnalyzer.goto();
// Splattershot Jr. has Splat Bomb sub
await compAnalyzer.selectWeapon(10);
await compAnalyzer.selectWeapon(40);
const damageCombos = compAnalyzer.damageCombos;
await expect(damageCombos.root).toBeVisible();
const initialDamageValues =
await damageCombos.damageValues.allTextContents();
await damageCombos.subDefenseSlider.fill("57");
const newDamageValues = await damageCombos.damageValues.allTextContents();
expect(initialDamageValues.join(",")).not.toEqual(
newDamageValues.join(","),
);
await damageCombos.subDefenseSlider.fill("0");
const initialInkTimes = await damageCombos.inkTimes.allTextContents();
await damageCombos.inkResistanceSlider.fill("57");
const newInkTimes = await damageCombos.inkTimes.allTextContents();
// ink resistance makes ink times longer or reveals more ink combos
if (initialInkTimes.length > 0 || newInkTimes.length > 0) {
const initialTotalFrames = initialInkTimes.reduce(
(sum, t) => sum + (Number.parseInt(t, 10) || 0),
0,
);
const newTotalFrames = newInkTimes.reduce(
(sum, t) => sum + (Number.parseInt(t, 10) || 0),
0,
);
expect(newTotalFrames).toBeGreaterThanOrEqual(initialTotalFrames);
}
const firstDamageTypeLabel = damageCombos.damageTypeLabels.first();
const damageTypeText = await firstDamageTypeLabel.textContent();
await expect(damageCombos.filteredItems).toHaveCount(0);
await firstDamageTypeLabel.click();
const filteredCount = await damageCombos.filteredItems.count();
expect(filteredCount).toBeGreaterThan(0);
await expect(damageCombos.filteredItems.first()).toContainText(
damageTypeText ?? "",
);
await damageCombos.filteredItems.first().click();
await expect(damageCombos.filteredItems).toHaveCount(filteredCount - 1);
})CompAnalyzerPage.gotoe2e/pages/comp-analyzer/comp-analyzer-page.ts:23
No JSDoc
async goto() {
await navigate({ page: this.page, url: COMP_ANALYZER_URL });
}CompAnalyzerPage.locators.selectedWeaponse2e/pages/comp-analyzer/comp-analyzer-page.ts:15
No JSDoc
page.getByTestId("selected-weapons")CompAnalyzerPage.locators.emptyWeaponSlotse2e/pages/comp-analyzer/comp-analyzer-page.ts:16
No JSDoc
page.getByText("Pick a weapon")CompAnalyzerPage.selectWeapone2e/pages/comp-analyzer/comp-analyzer-page.ts:39
No JSDoc
async selectWeapon(weaponSplId: MainWeaponId) {
await this.page.getByTestId(`weapon-button-${weaponSplId}`).click();
}CompAnalyzerPage.selectedWeapone2e/pages/comp-analyzer/comp-analyzer-page.ts:31
No JSDoc
selectedWeapon(index: number) {
return this.page.getByTestId(`selected-weapon-${index}`);
}CompAnalyzerPage.removeWeapone2e/pages/comp-analyzer/comp-analyzer-page.ts:43
No JSDoc
async removeWeapon(index: number) {
await this.page.getByTestId(`remove-weapon-${index}`).click();
}CompAnalyzerPage.locators.categorizationTogglee2e/pages/comp-analyzer/comp-analyzer-page.ts:18
No JSDoc
page.getByTestId("categorization-toggle")CompAnalyzerPagee2e/pages/comp-analyzer/comp-analyzer-page.ts:8
No JSDoc
CompAnalyzerPage.categorizationRadioe2e/pages/comp-analyzer/comp-analyzer-page.ts:35
No JSDoc
categorizationRadio(categorization: Categorization) {
return this.page.getByTestId(`categorization-${categorization}`);
}CompAnalyzerPage.selectCategorizatione2e/pages/comp-analyzer/comp-analyzer-page.ts:47
No JSDoc
async selectCategorization(categorization: Categorization) {
await this.categorizationRadio(categorization).click();
}CompAnalyzerPage.toggleWeaponGride2e/pages/comp-analyzer/comp-analyzer-page.ts:51
No JSDoc
async toggleWeaponGrid() {
await this.locators.weaponGridToggle.click();
}CompAnalyzerPage.damageCombose2e/pages/comp-analyzer/comp-analyzer-page.ts:27
No JSDoc
get damageCombos() {
return new DamageComboList(this.page.getByTestId("damage-combo-list"));
}CompAnalyzerPage.locators.rangeVisualizatione2e/pages/comp-analyzer/comp-analyzer-page.ts:19
No JSDoc
page.getByTestId("range-visualization")