S 1 module · 7 exports · 0 repositories · 25 e2e tests · 0 routes
Modules E2E tests Renders/ /to/:id /to/:id/info
Front page Side nav Arrange
Create tournament author Sendou name “Saved Tournament” start times inHours (1 ) → saved
const saved = await factories.TournamentFactory .create ({
authorId: ADMIN_ID ,
name: "Saved Tournament" ,
startTimes: [inHours (1 )],
});Create saved calendar event user N-ZAP tournament id saved.id
await factories.SavedCalendarEventFactory .create ({
userId: NZAP_TEST_ID ,
tournamentId: saved.id,
});Create tournament author Sendou name “Played Tournament” start times inHours (2 ) → played
const played = await factories.TournamentFactory .create ({
authorId: ADMIN_ID ,
name: "Played Tournament" ,
startTimes: [inHours (2 )],
});Create tournament team tournament id played.id member user ids N-ZAP
await factories.TournamentTeamFactory .create ({
tournamentId: played.id,
memberUserIds: [NZAP_TEST_ID ],
});Create scrim post starts at inHours (3 ) users user N-ZAP is owner 1
await factories.ScrimPostFactory .create ({
startsAt: inHours (3 ),
users: [{ userId: NZAP_TEST_ID , isOwner: 1 }],
});Create tournament author N-ZAP name “Organized Tournament” start times inHours (4 )
await factories.TournamentFactory .create ({
authorId: NZAP_TEST_ID ,
name: "Organized Tournament" ,
startTimes: [inHours (4 )],
});Front page Act
Open the front page
await new FrontPage (page).goto ();Side nav Assert
list items count is 4
await expect (sideNav.locators.listItems).toHaveCount (4 );sideNav.eventItem ("Saved Tournament" ), sideNav.eventItem ("Played Tournament" ), sideNav.eventItem ("Looking for scrim" ), sideNav.eventItem ("Organized Tournament" ) top to bottom
await expectTopToBottom ([
sideNav.eventItem ("Saved Tournament" ),
sideNav.eventItem ("Played Tournament" ),
sideNav.eventItem ("Looking for scrim" ),
sideNav.eventItem ("Organized Tournament" ),
]);item subtitle “Played Tournament” reads /\d{1 ,2 }:\d{2 }/
await expect (sideNav.itemSubtitle ("Played Tournament" )).toHaveText (
/\d{1 ,2 }:\d{2 }/,
);Act
Click event item “Played Tournament”
await sideNav.eventItem ("Played Tournament" ).click ();Assert
the page URL is new RegExp (`/to/${played.id}` )
await expect (page).toHaveURL (new RegExp (`/to/${played.id}` ));no error page
await expectNoErrorPage (page);Source test ("shows my tournaments, my scrims and saved events, soonest first" , async ({
page,
factories,
}) => {
const saved = await factories.TournamentFactory .create ({
authorId: ADMIN_ID ,
name: "Saved Tournament" ,
startTimes: [inHours (1 )],
});
await factories.SavedCalendarEventFactory .create ({
userId: NZAP_TEST_ID ,
tournamentId: saved.id,
});
const played = await factories.TournamentFactory .create ({
authorId: ADMIN_ID ,
name: "Played Tournament" ,
startTimes: [inHours (2 )],
});
await factories.TournamentTeamFactory .create ({
tournamentId: played.id,
memberUserIds: [NZAP_TEST_ID ],
});
await factories.ScrimPostFactory .create ({
startsAt: inHours (3 ),
users: [{ userId: NZAP_TEST_ID , isOwner: 1 }],
});
await factories.TournamentFactory .create ({
authorId: NZAP_TEST_ID ,
name: "Organized Tournament" ,
startTimes: [inHours (4 )],
});
await impersonate (page, NZAP_TEST_ID );
await new FrontPage (page).goto ();
const sideNav = new SideNav (page);
await expect (sideNav.locators.listItems).toHaveCount (4 );
await expectTopToBottom ([
sideNav.eventItem ("Saved Tournament" ),
sideNav.eventItem ("Played Tournament" ),
sideNav.eventItem ("Looking for scrim" ),
sideNav.eventItem ("Organized Tournament" ),
]);
await expect (sideNav.itemSubtitle ("Played Tournament" )).toHaveText (
/\d{1 ,2 }:\d{2 }/,
);
await sideNav.eventItem ("Played Tournament" ).click ();
await expect (page).toHaveURL (new RegExp (`/to/${played.id}` ));
await expectNoErrorPage (page);
})Renders/ /scrims /scrims/:id
Front page Side nav Front page Side nav Front page Side nav Arrange
Create 2 × user → [opponentOwner, otherPostOwner]
const [opponentOwner, otherPostOwner] =
await factories.UserFactory .createMany (2 );Create team name “Squid Squad” member user ids opponentOwner.id → opponentTeam
const opponentTeam = await factories.TeamFactory .create ({
name: "Squid Squad" ,
memberUserIds: [opponentOwner.id],
});Create scrim post starts at inHours (1 ) team id opponentTeam.id users user id opponentOwner.id is owner 1 requests users user N-ZAP is owner 1 is accepted true → booked
const booked = await factories.ScrimPostFactory .create (
{
startsAt: inHours (1 ),
teamId: opponentTeam.id,
users: [{ userId: opponentOwner.id, isOwner: 1 }],
},
{
requests: [
{ users: [{ userId: NZAP_TEST_ID , isOwner: 1 }], isAccepted: true },
],
},
);Create scrim post starts at inHours (2 ) users user N-ZAP is owner 1
await factories.ScrimPostFactory .create ({
startsAt: inHours (2 ),
users: [{ userId: NZAP_TEST_ID , isOwner: 1 }],
});Create scrim post starts at inHours (3 ) users user id otherPostOwner.id is owner 1 requests users user N-ZAP is owner 1 → pending
const pending = await factories.ScrimPostFactory .create (
{
startsAt: inHours (3 ),
users: [{ userId: otherPostOwner.id, isOwner: 1 }],
},
{ requests: [{ users: [{ userId: NZAP_TEST_ID , isOwner: 1 }] }] },
);Front page Act
Open the front page
await front.goto ();Side nav Assert
event item “vs. Squid Squad” is visible
await expect (sideNav.eventItem ("vs. Squid Squad" )).toBeVisible ();event item “Looking for scrim” is visible
await expect (sideNav.eventItem ("Looking for scrim" )).toBeVisible ();event item “Request pending” is visible
await expect (sideNav.eventItem ("Request pending" )).toBeVisible ();Act
Click event item “vs. Squid Squad”
await sideNav.eventItem ("vs. Squid Squad" ).click ();Assert
the page URL is `/scrims/${booked.id}`
await expect (page).toHaveURL (`/scrims/${booked.id}` );no error page
await expectNoErrorPage (page);Front page Act
Open the front page
await front.goto ();Side nav Act
Click event item “Looking for scrim”
await sideNav.eventItem ("Looking for scrim" ).click ();Assert
the page URL is “/scrims”
await expect (page).toHaveURL ("/scrims" );Front page Act
Open the front page
await front.goto ();Side nav Assert
event item “Request pending” has “href” = `/scrims?pendingRequestPostId=${pending.id}`
await expect (sideNav.eventItem ("Request pending" )).toHaveAttribute (
"href" ,
`/scrims?pendingRequestPostId=${pending.id}` ,
);Act
Click event item “Request pending”
await sideNav.eventItem ("Request pending" ).click ();Assert
the scrims page clears the param once it has scrolled to the post
the page URL is “/scrims”
await expect (page).toHaveURL ("/scrims" );no error page
await expectNoErrorPage (page);Source test ("scrim rows show their status and link to the right place" , async ({
page,
factories,
}) => {
const [opponentOwner, otherPostOwner] =
await factories.UserFactory .createMany (2 );
const opponentTeam = await factories.TeamFactory .create ({
name: "Squid Squad" ,
memberUserIds: [opponentOwner.id],
});
const booked = await factories.ScrimPostFactory .create (
{
startsAt: inHours (1 ),
teamId: opponentTeam.id,
users: [{ userId: opponentOwner.id, isOwner: 1 }],
},
{
requests: [
{ users: [{ userId: NZAP_TEST_ID , isOwner: 1 }], isAccepted: true },
],
},
);
await factories.ScrimPostFactory .create ({
startsAt: inHours (2 ),
users: [{ userId: NZAP_TEST_ID , isOwner: 1 }],
});
const pending = await factories.ScrimPostFactory .create (
{
startsAt: inHours (3 ),
users: [{ userId: otherPostOwner.id, isOwner: 1 }],
},
{ requests: [{ users: [{ userId: NZAP_TEST_ID , isOwner: 1 }] }] },
);
await impersonate (page, NZAP_TEST_ID );
const front = new FrontPage (page);
await front.goto ();
const sideNav = new SideNav (page);
await expect (sideNav.eventItem ("vs. Squid Squad" )).toBeVisible ();
await expect (sideNav.eventItem ("Looking for scrim" )).toBeVisible ();
await expect (sideNav.eventItem ("Request pending" )).toBeVisible ();
await sideNav.eventItem ("vs. Squid Squad" ).click ();
await expect (page).toHaveURL (`/scrims/${booked.id}` );
await expectNoErrorPage (page);
await front.goto ();
await sideNav.eventItem ("Looking for scrim" ).click ();
await expect (page).toHaveURL ("/scrims" );
await front.goto ();
await expect (sideNav.eventItem ("Request pending" )).toHaveAttribute (
"href" ,
`/scrims?pendingRequestPostId=${pending.id}` ,
);
await sideNav.eventItem ("Request pending" ).click ();
// the scrims page clears the param once it has scrolled to the post
await expect (page).toHaveURL ("/scrims" );
await expectNoErrorPage (page);
})caps at five events and View all opens the events page Renders/ /events
Front page Side nav Events page Arrange
For each nth of 1 , 2 , 3 , 4 , 5 , 6 , 7
for (const nth of [1 , 2 , 3 , 4 , 5 , 6 , 7 ]) {
const tournament = await factories.TournamentFactory .create ({
authorId: ADMIN_ID ,
name: `Tournament ${nth}` ,
startTimes: [inHours (nth)],
});
await factories.TournamentTeamFactory .create ({
tournamentId: tournament.id,
memberUserIds: [NZAP_TEST_ID ],
});
}Create tournament author Sendou name `Tournament ${nth}` start times inHours (nth) → tournament
const tournament = await factories.TournamentFactory .create ({
authorId: ADMIN_ID ,
name: `Tournament ${nth}` ,
startTimes: [inHours (nth)],
});Create tournament team tournament id tournament.id member user ids N-ZAP
await factories.TournamentTeamFactory .create ({
tournamentId: tournament.id,
memberUserIds: [NZAP_TEST_ID ],
});Front page Act
Open the front page
await new FrontPage (page).goto ();Side nav Assert
list items count is 5
await expect (sideNav.locators.listItems).toHaveCount (5 );event item “Tournament 5” is visible
await expect (sideNav.eventItem ("Tournament 5" )).toBeVisible ();event item “Tournament 6” count is 0
await expect (sideNav.eventItem ("Tournament 6" )).toHaveCount (0 );Act
Click view all link “Events”
await sideNav.viewAllLink ("Events" ).click ();Assert
the page URL is EVENTS_PAGE
await expect (page).toHaveURL (EVENTS_PAGE );Events page Assert
event link “Tournament 6” is visible
await expect (events.eventLink ("Tournament 6" )).toBeVisible ();event link “Tournament 7” is visible
await expect (events.eventLink ("Tournament 7" )).toBeVisible ();Source test ("caps at five events and View all opens the events page" , async ({
page,
factories,
}) => {
for (const nth of [1 , 2 , 3 , 4 , 5 , 6 , 7 ]) {
const tournament = await factories.TournamentFactory .create ({
authorId: ADMIN_ID ,
name: `Tournament ${nth}` ,
startTimes: [inHours (nth)],
});
await factories.TournamentTeamFactory .create ({
tournamentId: tournament.id,
memberUserIds: [NZAP_TEST_ID ],
});
}
await impersonate (page, NZAP_TEST_ID );
await new FrontPage (page).goto ();
const sideNav = new SideNav (page);
await expect (sideNav.locators.listItems).toHaveCount (5 );
await expect (sideNav.eventItem ("Tournament 5" )).toBeVisible ();
await expect (sideNav.eventItem ("Tournament 6" )).toHaveCount (0 );
await sideNav.viewAllLink ("Events" ).click ();
await expect (page).toHaveURL (EVENTS_PAGE );
const events = new EventsPage (page);
await expect (events.eventLink ("Tournament 6" )).toBeVisible ();
await expect (events.eventLink ("Tournament 7" )).toBeVisible ();
})Renders/
Front page Side nav Front page Act
Open the front page
await new FrontPage (page).goto ();Side nav Assert
empty text NO_EVENTS_TEXT is visible
await expect (sideNav.emptyText (NO_EVENTS_TEXT )).toBeVisible ();view all link “Events” is visible
await expect (sideNav.viewAllLink ("Events" )).toBeVisible ();Source test ("shows an empty state without upcoming events" , async ({ page }) => {
await impersonate (page, NZAP_TEST_ID );
await new FrontPage (page).goto ();
const sideNav = new SideNav (page);
await expect (sideNav.emptyText (NO_EVENTS_TEXT )).toBeVisible ();
await expect (sideNav.viewAllLink ("Events" )).toBeVisible ();
})Renders/
Front page Friend row Friend row Friend row Friend row Arrange
Create named users “IdleFriend” , “QueueFriend” , “SubFriend” , “MatchFriend” , “GroupMate” → [idle, queueing, sub, inMatch, groupMate]
const [idle, queueing, sub, inMatch, groupMate] = await createNamedUsers (
factories,
["IdleFriend" , "QueueFriend" , "SubFriend" , "MatchFriend" , "GroupMate" ],
);Befriend idle.id, queueing.id, sub.id, inMatch.id
await befriend (factories, [idle.id, queueing.id, sub.id, inMatch.id]);Create SQ group member user ids queueing.id, groupMate.id
await factories.SQGroupFactory .create ({
memberUserIds: [queueing.id, groupMate.id],
});Create sub seeking tournament name “Sub Tournament” sub id sub.id
await createSubSeekingTournament (factories, {
name: "Sub Tournament" ,
subId: sub.id,
});Create in progress match name “Match Tournament” friend id inMatch.id
await createInProgressMatch (factories, {
name: "Match Tournament" ,
friendId: inMatch.id,
});Front page Act
Open the front page
await new FrontPage (page).goto ();Side nav
Act
Friend “IdleFriend” → idleRow
const idleRow = sideNav.friend ("IdleFriend" );Friend row Assert
trigger is visible
await expect (idleRow.trigger).toBeVisible ();subtitle count is 0
await expect (idleRow.locators.subtitle).toHaveCount (0 );badge count is 0
await expect (idleRow.locators.badge).toHaveCount (0 );Side nav
Act
Friend “QueueFriend” → queueingRow
const queueingRow = sideNav.friend ("QueueFriend" );Friend row Assert
subtitle reads “SendouQ”
await expect (queueingRow.locators.subtitle).toHaveText ("SendouQ" );badge reads “2/4”
await expect (queueingRow.locators.badge).toHaveText ("2/4" );Side nav
Act
Friend “SubFriend” → subRow
const subRow = sideNav.friend ("SubFriend" );Friend row Assert
subtitle reads “Sub Tournament”
await expect (subRow.locators.subtitle).toHaveText ("Sub Tournament" );badge reads “1/4”
await expect (subRow.locators.badge).toHaveText ("1/4" );Side nav
Act
Friend “MatchFriend” → inMatchRow
const inMatchRow = sideNav.friend ("MatchFriend" );Friend row Assert
subtitle reads “Match Tournament”
await expect (inMatchRow.locators.subtitle).toHaveText ("Match Tournament" );badge reads “Match”
await expect (inMatchRow.locators.badge).toHaveText ("Match" );Source test ("shows what each friend is doing right now" , async ({
page,
factories,
}) => {
const [idle, queueing, sub, inMatch, groupMate] = await createNamedUsers (
factories,
["IdleFriend" , "QueueFriend" , "SubFriend" , "MatchFriend" , "GroupMate" ],
);
await befriend (factories, [idle.id, queueing.id, sub.id, inMatch.id]);
await factories.SQGroupFactory .create ({
memberUserIds: [queueing.id, groupMate.id],
});
await createSubSeekingTournament (factories, {
name: "Sub Tournament" ,
subId: sub.id,
});
await createInProgressMatch (factories, {
name: "Match Tournament" ,
friendId: inMatch.id,
});
await impersonate (page, NZAP_TEST_ID );
await new FrontPage (page).goto ();
const sideNav = new SideNav (page);
const idleRow = sideNav.friend ("IdleFriend" );
await expect (idleRow.trigger).toBeVisible ();
await expect (idleRow.locators.subtitle).toHaveCount (0 );
await expect (idleRow.locators.badge).toHaveCount (0 );
const queueingRow = sideNav.friend ("QueueFriend" );
await expect (queueingRow.locators.subtitle).toHaveText ("SendouQ" );
await expect (queueingRow.locators.badge).toHaveText ("2/4" );
const subRow = sideNav.friend ("SubFriend" );
await expect (subRow.locators.subtitle).toHaveText ("Sub Tournament" );
await expect (subRow.locators.badge).toHaveText ("1/4" );
const inMatchRow = sideNav.friend ("MatchFriend" );
await expect (inMatchRow.locators.subtitle).toHaveText ("Match Tournament" );
await expect (inMatchRow.locators.badge).toHaveText ("Match" );
})friend menu actions of SendouQ friends land on a real page Renders/ /q/looking /q/match/:id /u/:identifier /u/:identifier
Front page Friend row Front page Friend row Front page Friend row Arrange
Create named users “SidebarUser” , “IdleFriend” , “QueueFriend” , “MatchFriend” → [me, idle, queueing, inSendouQMatch]
const [me, idle, queueing, inSendouQMatch] = await createNamedUsers (
factories,
["SidebarUser" , "IdleFriend" , "QueueFriend" , "MatchFriend" ],
);Befriend idle.id, queueing.id, inSendouQMatch.id, me.id
await befriend (factories, [idle.id, queueing.id, inSendouQMatch.id], me.id);Create SQ group member user ids queueing.id
await factories.SQGroupFactory .create ({ memberUserIds: [queueing.id] });Create SQ match alpha user ids inSendouQMatch.id, ...(await createUserIds (factories, 3 )) bravo user ids createUserIds (factories, 4 ) → match
const match = await factories.SQMatchFactory .create ({
alphaUserIds: [inSendouQMatch.id, ...(await createUserIds (factories, 3 ))],
bravoUserIds: await createUserIds (factories, 4 ),
});Front page Act
Open the front page
await front.goto ();Side nav
Act
Friend “IdleFriend” → idleRow
const idleRow = sideNav.friend ("IdleFriend" );Friend row Act
Open menu
await idleRow.openMenu ();Assert
menu item “Delete friend” count is 0
await expect (idleRow.menuItem ("Delete friend" )).toHaveCount (0 );Act
Click menu item “View user page”
await idleRow.menuItem ("View user page" ).click ();Assert
the page URL is /\/u\//
await expect (page).toHaveURL (/\/u\//); no error page
await expectNoErrorPage (page);Front page Act
Open the front page
await front.goto ();Side nav
Act
Friend “MatchFriend” → matchRow
const matchRow = sideNav.friend ("MatchFriend" );Friend row Act
Open menu
await matchRow.openMenu ();Click menu item “View match”
await matchRow.menuItem ("View match" ).click ();Assert
the page URL is sendouQMatchPage (match.id)
await expect (page).toHaveURL (sendouQMatchPage (match.id));no error page
await expectNoErrorPage (page);Front page Act
Open the front page
await front.goto ();Side nav
Act
Friend “QueueFriend” → queueingRow
const queueingRow = sideNav.friend ("QueueFriend" );Friend row Act
Open menu
await queueingRow.openMenu ();Click menu item “Join SendouQ”
await waitForPOSTResponse (page, () =>
queueingRow.menuItem ("Join SendouQ" ).click (),
);Assert
the page URL is SENDOUQ_LOOKING_PAGE
await expect (page).toHaveURL (SENDOUQ_LOOKING_PAGE );no error page
await expectNoErrorPage (page);Source test ("friend menu actions of SendouQ friends land on a real page" , async ({
page,
factories,
}) => {
const [me, idle, queueing, inSendouQMatch] = await createNamedUsers (
factories,
["SidebarUser" , "IdleFriend" , "QueueFriend" , "MatchFriend" ],
);
await befriend (factories, [idle.id, queueing.id, inSendouQMatch.id], me.id);
await factories.SQGroupFactory .create ({ memberUserIds: [queueing.id] });
const match = await factories.SQMatchFactory .create ({
alphaUserIds: [inSendouQMatch.id, ...(await createUserIds (factories, 3 ))],
bravoUserIds: await createUserIds (factories, 4 ),
});
await impersonate (page, me.id);
const front = new FrontPage (page);
await front.goto ();
const sideNav = new SideNav (page);
const idleRow = sideNav.friend ("IdleFriend" );
await idleRow.openMenu ();
await expect (idleRow.menuItem ("Delete friend" )).toHaveCount (0 );
await idleRow.menuItem ("View user page" ).click ();
await expect (page).toHaveURL (/\/u\//);
await expectNoErrorPage (page);
await front.goto ();
const matchRow = sideNav.friend ("MatchFriend" );
await matchRow.openMenu ();
await matchRow.menuItem ("View match" ).click ();
await expect (page).toHaveURL (sendouQMatchPage (match.id));
await expectNoErrorPage (page);
await front.goto ();
const queueingRow = sideNav.friend ("QueueFriend" );
await queueingRow.openMenu ();
await waitForPOSTResponse (page, () =>
queueingRow.menuItem ("Join SendouQ" ).click (),
);
await expect (page).toHaveURL (SENDOUQ_LOOKING_PAGE );
await expectNoErrorPage (page);
})friend menu actions of tournament friends land on a real page Renders/ /to/:id /to/:id/looking /to/:id/matches/:mid /to/:id/brackets
Front page Friend row Front page Friend row Front page Friend row Arrange
Create named users “SubFriend” , “MatchFriend” , “WaitingFriend” → [sub, inMatch, waiting]
const [sub, inMatch, waiting] = await createNamedUsers (factories, [
"SubFriend" ,
"MatchFriend" ,
"WaitingFriend" ,
]);Befriend sub.id, inMatch.id, waiting.id
await befriend (factories, [sub.id, inMatch.id, waiting.id]);Create sub seeking tournament name “Sub Tournament” sub id sub.id → { tournament: subTournament }
const { tournament: subTournament } = await createSubSeekingTournament (
factories,
{ name: "Sub Tournament" , subId: sub.id },
);Create in progress match name “Match Tournament” friend id inMatch.id → { tournament, matchId }
const { tournament, matchId } = await createInProgressMatch (factories, {
name: "Match Tournament" ,
friendId: inMatch.id,
});Create tournament with bye team name “Waiting Tournament” waiting user id waiting.id → { tournament: waitingTournament }
const { tournament: waitingTournament } = await createTournamentWithByeTeam (
factories,
{ name: "Waiting Tournament" , waitingUserId: waiting.id },
);Front page Act
Open the front page
await front.goto ();Side nav
Act
Friend “SubFriend” → subRow
const subRow = sideNav.friend ("SubFriend" );Friend row Act
Open menu
await subRow.openMenu ();Click menu item “View tournament”
await subRow.menuItem ("View tournament" ).click ();Assert
the page URL is tournamentSubsPage (subTournament.id)
await expect (page).toHaveURL (tournamentSubsPage (subTournament.id));no error page
await expectNoErrorPage (page);Front page Act
Open the front page
await front.goto ();Side nav
Act
Friend “WaitingFriend” → waitingRow
const waitingRow = sideNav.friend ("WaitingFriend" );Friend row Assert
badge reads “Next”
await expect (waitingRow.locators.badge).toHaveText ("Next" );Act
Open menu
await waitingRow.openMenu ();Click menu item “View tournament”
await waitingRow.menuItem ("View tournament" ).click ();Assert
the page URL is new RegExp (`/to/${waitingTournament.id}(/|$)` )
await expect (page).toHaveURL (
new RegExp (`/to/${waitingTournament.id}(/|$)` ),
);no error page
await expectNoErrorPage (page);Front page Act
Open the front page
await front.goto ();Side nav
Act
Friend “MatchFriend” → inMatchRow
const inMatchRow = sideNav.friend ("MatchFriend" );Friend row Act
Open menu
await inMatchRow.openMenu ();Click menu item “View match”
await inMatchRow.menuItem ("View match" ).click ();Assert
the page URL is tournamentMatchPage ({ tournamentId: tournament.id, matchId })
await expect (page).toHaveURL (
tournamentMatchPage ({ tournamentId: tournament.id, matchId }),
);no error page
await expectNoErrorPage (page);Source test ("friend menu actions of tournament friends land on a real page" , async ({
page,
factories,
}) => {
const [sub, inMatch, waiting] = await createNamedUsers (factories, [
"SubFriend" ,
"MatchFriend" ,
"WaitingFriend" ,
]);
await befriend (factories, [sub.id, inMatch.id, waiting.id]);
const { tournament: subTournament } = await createSubSeekingTournament (
factories,
{ name: "Sub Tournament" , subId: sub.id },
);
const { tournament, matchId } = await createInProgressMatch (factories, {
name: "Match Tournament" ,
friendId: inMatch.id,
});
const { tournament: waitingTournament } = await createTournamentWithByeTeam (
factories,
{ name: "Waiting Tournament" , waitingUserId: waiting.id },
);
await impersonate (page, NZAP_TEST_ID );
const front = new FrontPage (page);
await front.goto ();
const sideNav = new SideNav (page);
const subRow = sideNav.friend ("SubFriend" );
await subRow.openMenu ();
await subRow.menuItem ("View tournament" ).click ();
await expect (page).toHaveURL (tournamentSubsPage (subTournament.id));
await expectNoErrorPage (page);
await front.goto ();
const waitingRow = sideNav.friend ("WaitingFriend" );
await expect (waitingRow.locators.badge).toHaveText ("Next" );
await waitingRow.openMenu ();
await waitingRow.menuItem ("View tournament" ).click ();
await expect (page).toHaveURL (
new RegExp (`/to/${waitingTournament.id}(/|$)` ),
);
await expectNoErrorPage (page);
await front.goto ();
const inMatchRow = sideNav.friend ("MatchFriend" );
await inMatchRow.openMenu ();
await inMatchRow.menuItem ("View match" ).click ();
await expect (page).toHaveURL (
tournamentMatchPage ({ tournamentId: tournament.id, matchId }),
);
await expectNoErrorPage (page);
})Renders/ /friends
Front page Side nav Front page Mobile nav Arrange
names = Array .from ( { length: 10 }, (_, index) => `Friend$ {String (index + 1 ).padStart…
const names = Array .from (
{ length: 10 },
(_, index) => `Friend${String(index + 1).padStart(2, "0")}` ,
);Create named users names → friends
const friends = await createNamedUsers (factories, names);Befriend friends.map ((friend) => friend.id)
await befriend (
factories,
friends.map ((friend) => friend.id),
);Front page Act
Open the front page
await front.goto ();Side nav Assert
friend items count is 4
await expect (sideNav.locators.friendItems).toHaveCount (4 );Arrange
Use a MOBILE_VIEWPORT viewport
await page.setViewportSize (MOBILE_VIEWPORT );Front page Act
Open the front page
await front.goto ();Mobile nav Act
Open panel “friends”
await mobileNav.openPanel ("friends" );Assert
friend items count is 8
await expect (mobileNav.locators.friendItems).toHaveCount (8 );Act
Click view all link
await mobileNav.locators.viewAllLink.click ();Assert
the page URL is FRIENDS_PAGE
await expect (page).toHaveURL (FRIENDS_PAGE );For each name of names
for (const name of names) {
await expect (friendsPage.friendButton (name)).toBeVisible ();
}friend button name is visible
await expect (friendsPage.friendButton (name)).toBeVisible ();Source test ("shows four friends on desktop, eight in the mobile panel" , async ({
page,
factories,
}) => {
const names = Array .from (
{ length: 10 },
(_, index) => `Friend${String(index + 1).padStart(2, "0")}` ,
);
const friends = await createNamedUsers (factories, names);
await befriend (
factories,
friends.map ((friend) => friend.id),
);
await impersonate (page, NZAP_TEST_ID );
const front = new FrontPage (page);
await front.goto ();
const sideNav = new SideNav (page);
await expect (sideNav.locators.friendItems).toHaveCount (4 );
await page.setViewportSize (MOBILE_VIEWPORT );
await front.goto ();
const mobileNav = new MobileNav (page);
await mobileNav.openPanel ("friends" );
await expect (mobileNav.locators.friendItems).toHaveCount (8 );
await mobileNav.locators.viewAllLink.click ();
await expect (page).toHaveURL (FRIENDS_PAGE );
const friendsPage = new FriendsPage (page);
for (const name of names) {
await expect (friendsPage.friendButton (name)).toBeVisible ();
}
})Renders/ /friends
Front page Side nav Friends page Front page Side nav Arrange
Create 2 × user → requesters
const requesters = await factories.UserFactory .createMany (2 );For each requester of requesters
for (const requester of requesters) {
await factories.FriendRequestFactory .create ({
senderId: requester.id,
receiverId: NZAP_TEST_ID ,
});
}Create friend request sender id requester.id receiver N-ZAP
await factories.FriendRequestFactory .create ({
senderId: requester.id,
receiverId: NZAP_TEST_ID ,
});Front page Act
Open the front page
await front.goto ();Side nav Assert
unseen requests badge reads “2”
await expect (sideNav.locators.unseenRequestsBadge).toHaveText ("2" );Act
Toggle collapse
await sideNav.toggleCollapse ();Assert
collapsed requests badge reads “2”
await expect (sideNav.collapsedRequestsBadge).toHaveText ("2" );Friends page Act
Open the friends page
await friendsPage.goto ();Accept request
await friendsPage.acceptRequest ();Front page Act
Open the front page
await front.goto ();Side nav Assert
unseen requests badge count is 0
await expect (sideNav.locators.unseenRequestsBadge).toHaveCount (0 );Source test ("unseen friend requests show as a badge" , async ({
page,
factories,
}) => {
const requesters = await factories.UserFactory .createMany (2 );
for (const requester of requesters) {
await factories.FriendRequestFactory .create ({
senderId: requester.id,
receiverId: NZAP_TEST_ID ,
});
}
await impersonate (page, NZAP_TEST_ID );
const front = new FrontPage (page);
await front.goto ();
const sideNav = new SideNav (page);
await expect (sideNav.locators.unseenRequestsBadge).toHaveText ("2" );
await sideNav.toggleCollapse ();
await expect (sideNav.collapsedRequestsBadge).toHaveText ("2" );
const friendsPage = new FriendsPage (page);
await friendsPage.goto ();
await friendsPage.acceptRequest ();
await front.goto ();
await expect (sideNav.locators.unseenRequestsBadge).toHaveCount (0 );
})Renders/
Front page Side nav Front page Side nav Front page Act
Open the front page
await front.goto ();Side nav Assert
empty text LOGGED_OUT_FRIENDS_TEXT is visible
await expect (sideNav.emptyText (LOGGED_OUT_FRIENDS_TEXT )).toBeVisible ();view all link “Friends” count is 0
await expect (sideNav.viewAllLink ("Friends" )).toHaveCount (0 );Front page Act
Open the front page
await front.goto ();Side nav Assert
empty text NO_FRIENDS_TEXT is visible
await expect (sideNav.emptyText (NO_FRIENDS_TEXT )).toBeVisible ();view all link “Friends” is visible
await expect (sideNav.viewAllLink ("Friends" )).toBeVisible ();Source test ("shows an empty state for both logged out and friendless users" , async ({
page,
}) => {
const front = new FrontPage (page);
await front.goto ();
const sideNav = new SideNav (page);
await expect (sideNav.emptyText (LOGGED_OUT_FRIENDS_TEXT )).toBeVisible ();
await expect (sideNav.viewAllLink ("Friends" )).toHaveCount (0 );
await impersonate (page, NZAP_TEST_ID );
await front.goto ();
await expect (sideNav.emptyText (NO_FRIENDS_TEXT )).toBeVisible ();
await expect (sideNav.viewAllLink ("Friends" )).toBeVisible ();
})Renders/
Side nav Arrange
Create named users “StreamFriend” , “StreamTeammate” , “StreamOpponent” → [friend, teammate, opponent]
const [friend, teammate, opponent] = await createNamedUsers (factories, [
"StreamFriend" ,
"StreamTeammate" ,
"StreamOpponent" ,
]);Befriend friend.id
await befriend (factories, [friend.id]);Create in progress match name “Match Tournament” friend id friend.id teammate id teammate.id opponent id opponent.id → { tournament, matchId }
const { tournament, matchId } = await createInProgressMatch (factories, {
name: "Match Tournament" ,
friendId: friend.id,
teammateId: teammate.id,
opponentId: opponent.id,
});Cast match tournament tournament id tournament.id matchId twitch account “cast_account”
await factories.TournamentFactory .castMatch ({
tournamentId: tournament.id,
matchId,
twitchAccount: CAST_ACCOUNT ,
});Side nav Act
Friend “StreamFriend” → friendRow
const friendRow = new SideNav (page).friend ("StreamFriend" );Arrange
expectWatchStream = async (account: string ) => { await front.goto (); await expect (friendRow.locat…
const expectWatchStream = async (account: string ) => {
await front.goto ();
await expect (friendRow.locators.badge).toHaveText ("Live" );
await friendRow.openMenu ();
expect (await friendRow.watchStreamHref ()).toBe (twitchUrl (account));
};Replace all live stream user id friend.id
await factories.LiveStreamFactory .replaceAll ([{ userId: friend.id }]);Assert
streamAccountOf (friend.id) watch stream
await expectWatchStream (streamAccountOf (friend.id));Arrange
Replace all live stream user id teammate.id
await factories.LiveStreamFactory .replaceAll ([{ userId: teammate.id }]);Assert
streamAccountOf (teammate.id) watch stream
await expectWatchStream (streamAccountOf (teammate.id));Arrange
Replace all live stream user id null account “cast_account”
await factories.LiveStreamFactory .replaceAll ([
{ userId: null , account: CAST_ACCOUNT },
]);Assert
“cast_account” watch stream
await expectWatchStream (CAST_ACCOUNT );Arrange
Replace all live stream user id opponent.id
await factories.LiveStreamFactory .replaceAll ([{ userId: opponent.id }]);Assert
streamAccountOf (opponent.id) watch stream
await expectWatchStream (streamAccountOf (opponent.id));Arrange
Replace all live stream user id friend.id , user id teammate.id , user id opponent.id , user id null account “cast_account”
await factories.LiveStreamFactory .replaceAll ([
{ userId: friend.id },
{ userId: teammate.id },
{ userId: opponent.id },
{ userId: null , account: CAST_ACCOUNT },
]);Assert
streamAccountOf (friend.id) watch stream
await expectWatchStream (streamAccountOf (friend.id));Source test ("picks the best available stream for a friend's tournament match" , async ({
page,
factories,
}) => {
const [friend, teammate, opponent] = await createNamedUsers (factories, [
"StreamFriend" ,
"StreamTeammate" ,
"StreamOpponent" ,
]);
await befriend (factories, [friend.id]);
const { tournament, matchId } = await createInProgressMatch (factories, {
name: "Match Tournament" ,
friendId: friend.id,
teammateId: teammate.id,
opponentId: opponent.id,
});
await factories.TournamentFactory .castMatch ({
tournamentId: tournament.id,
matchId,
twitchAccount: CAST_ACCOUNT ,
});
await impersonate (page, NZAP_TEST_ID );
const front = new FrontPage (page);
const friendRow = new SideNav (page).friend ("StreamFriend" );
const expectWatchStream = async (account: string ) => {
await front.goto ();
await expect (friendRow.locators.badge).toHaveText ("Live" );
await friendRow.openMenu ();
expect (await friendRow.watchStreamHref ()).toBe (twitchUrl (account));
};
await factories.LiveStreamFactory .replaceAll ([{ userId: friend.id }]);
await expectWatchStream (streamAccountOf (friend.id));
await factories.LiveStreamFactory .replaceAll ([{ userId: teammate.id }]);
await expectWatchStream (streamAccountOf (teammate.id));
await factories.LiveStreamFactory .replaceAll ([
{ userId: null , account: CAST_ACCOUNT },
]);
await expectWatchStream (CAST_ACCOUNT );
await factories.LiveStreamFactory .replaceAll ([{ userId: opponent.id }]);
await expectWatchStream (streamAccountOf (opponent.id));
await factories.LiveStreamFactory .replaceAll ([
{ userId: friend.id },
{ userId: teammate.id },
{ userId: opponent.id },
{ userId: null , account: CAST_ACCOUNT },
]);
await expectWatchStream (streamAccountOf (friend.id));
})Renders/
Front page Friend row Arrange
Create named users “StreamFriend” → [friend]
const [friend] = await createNamedUsers (factories, ["StreamFriend" ]);Befriend friend.id
await befriend (factories, [friend.id]);Create in progress match name “Match Tournament” friend id friend.id
await createInProgressMatch (factories, {
name: "Match Tournament" ,
friendId: friend.id,
});Replace all live stream user id friend.id
await factories.LiveStreamFactory .replaceAll ([{ userId: friend.id }]);Act
stubbed rather than aborted so the popup keeps the URL it was opened with
Route “https://twitch.tv/**” , (route) => route.fulfill ({ status: 200 , contentType: "text/html" , body: "<htm…
await page.context ().route ("https://twitch.tv/**" , (route) =>
route.fulfill ({
status: 200 ,
contentType: "text/html" ,
body: "<html lang='en'><head><title>Twitch</title></head><body></body></html>" ,
}),
);Front page Act
Open the front page
await new FrontPage (page).goto ();Side nav
Act
Friend “StreamFriend” → friendRow
const friendRow = new SideNav (page).friend ("StreamFriend" );Friend row Act
Open menu
await friendRow.openMenu ();Menu item “Watch stream” → watchStream
const watchStream = friendRow.menuItem ("Watch stream" );Assert
watchStream has “href” = twitchUrl (streamAccountOf (friend.id))
await expect (watchStream).toHaveAttribute (
"href" ,
twitchUrl (streamAccountOf (friend.id)),
);watchStream has “target” = “_blank”
await expect (watchStream).toHaveAttribute ("target" , "_blank" );watchStream has “rel” = “noreferrer”
await expect (watchStream).toHaveAttribute ("rel" , "noreferrer" );Act
Catch () => null → popupPromise
const popupPromise = page
.context ()
.waitForEvent ("page" , { timeout: 5_000 })
.catch (() => null );Click watchStream
await watchStream.click ();popup = popupPromise
const popup = await popupPromise;If popup
if (popup) {
expect (popup.url ()).toContain ("twitch.tv" );
await popup.close ();
}popup.url () contains “twitch.tv”
expect (popup.url ()).toContain ("twitch.tv" );Close
await popup.close ();Assert
the page URL is “/”
await expect (page).toHaveURL ("/" );no error page
await expectNoErrorPage (page);Source test ("watch stream opens Twitch, not an in-app error page" , async ({
page,
factories,
}) => {
const [friend] = await createNamedUsers (factories, ["StreamFriend" ]);
await befriend (factories, [friend.id]);
await createInProgressMatch (factories, {
name: "Match Tournament" ,
friendId: friend.id,
});
await factories.LiveStreamFactory .replaceAll ([{ userId: friend.id }]);
// stubbed rather than aborted so the popup keeps the URL it was opened with
await page.context ().route ("https://twitch.tv/**" , (route) =>
route.fulfill ({
status: 200 ,
contentType: "text/html" ,
body: "<html lang='en'><head><title>Twitch</title></head><body></body></html>" ,
}),
);
await impersonate (page, NZAP_TEST_ID );
await new FrontPage (page).goto ();
const friendRow = new SideNav (page).friend ("StreamFriend" );
await friendRow.openMenu ();
const watchStream = friendRow.menuItem ("Watch stream" );
await expect (watchStream).toHaveAttribute (
"href" ,
twitchUrl (streamAccountOf (friend.id)),
);
await expect (watchStream).toHaveAttribute ("target" , "_blank" );
await expect (watchStream).toHaveAttribute ("rel" , "noreferrer" );
const popupPromise = page
.context ()
.waitForEvent ("page" , { timeout: 5_000 })
.catch (() => null );
await watchStream.click ();
const popup = await popupPromise;
if (popup) {
expect (popup.url ()).toContain ("twitch.tv" );
await popup.close ();
}
await expect (page).toHaveURL ("/" );
await expectNoErrorPage (page);
})shows no stream when nobody streams the friend's match Renders/
Front page Friend row Front page Friend row Arrange
the friend has a Twitch account on their profile throughout: only an actually live stream may turn the row live
Create named users “StreamFriend” , “Outsider” , twitch “friend_twitch” → [friend, outsider]
const [friend, outsider] = await createNamedUsers (
factories,
["StreamFriend" , "Outsider" ],
{ twitch: "friend_twitch" },
);Befriend friend.id
await befriend (factories, [friend.id]);Create in progress match name “Match Tournament” friend id friend.id → { tournament, matchId }
const { tournament, matchId } = await createInProgressMatch (factories, {
name: "Match Tournament" ,
friendId: friend.id,
});Front page Act
Open the front page
await front.goto ();Side nav
Act
Friend “StreamFriend” → friendRow
const friendRow = new SideNav (page).friend ("StreamFriend" );Friend row Assert
badge reads “Match”
await expect (friendRow.locators.badge).toHaveText ("Match" );Act
Open menu
await friendRow.openMenu ();Assert
menu item “View user page” is visible
await expect (friendRow.menuItem ("View user page" )).toBeVisible ();menu item “View match” has “href” = tournamentMatchPage ({ tournamentId: tournament.id, matchId })
await expect (friendRow.menuItem ("View match" )).toHaveAttribute (
"href" ,
tournamentMatchPage ({ tournamentId: tournament.id, matchId }),
);menu item “Watch stream” count is 0
await expect (friendRow.menuItem ("Watch stream" )).toHaveCount (0 );Arrange
Replace all live stream user id outsider.id
await factories.LiveStreamFactory .replaceAll ([{ userId: outsider.id }]);Front page Act
Open the front page
await front.goto ();Friend row Assert
badge reads “Match”
await expect (friendRow.locators.badge).toHaveText ("Match" );Act
Open menu
await friendRow.openMenu ();Assert
menu item “Watch stream” count is 0
await expect (friendRow.menuItem ("Watch stream" )).toHaveCount (0 );Source test ("shows no stream when nobody streams the friend's match" , async ({
page,
factories,
}) => {
// the friend has a Twitch account on their profile throughout: only an
// actually live stream may turn the row live
const [friend, outsider] = await createNamedUsers (
factories,
["StreamFriend" , "Outsider" ],
{ twitch: "friend_twitch" },
);
await befriend (factories, [friend.id]);
const { tournament, matchId } = await createInProgressMatch (factories, {
name: "Match Tournament" ,
friendId: friend.id,
});
await impersonate (page, NZAP_TEST_ID );
const front = new FrontPage (page);
await front.goto ();
const friendRow = new SideNav (page).friend ("StreamFriend" );
await expect (friendRow.locators.badge).toHaveText ("Match" );
await friendRow.openMenu ();
await expect (friendRow.menuItem ("View user page" )).toBeVisible ();
await expect (friendRow.menuItem ("View match" )).toHaveAttribute (
"href" ,
tournamentMatchPage ({ tournamentId: tournament.id, matchId }),
);
await expect (friendRow.menuItem ("Watch stream" )).toHaveCount (0 );
await factories.LiveStreamFactory .replaceAll ([{ userId: outsider.id }]);
await front.goto ();
await expect (friendRow.locators.badge).toHaveText ("Match" );
await friendRow.openMenu ();
await expect (friendRow.menuItem ("Watch stream" )).toHaveCount (0 );
})Renders/
Front page Friend row Arrange
Create named users “StreamFriend” → [friend]
const [friend] = await createNamedUsers (factories, ["StreamFriend" ]);Befriend friend.id
await befriend (factories, [friend.id]);Create in progress match name “Match Tournament” friend id friend.id → { tournament, matchId }
const { tournament, matchId } = await createInProgressMatch (factories, {
name: "Match Tournament" ,
friendId: friend.id,
});Cast match tournament tournament id tournament.id matchId twitch account “cast_account”
await factories.TournamentFactory .castMatch ({
tournamentId: tournament.id,
matchId,
twitchAccount: CAST_ACCOUNT ,
});Front page Act
Open the front page
await new FrontPage (page).goto ();Side nav
Act
Friend “StreamFriend” → friendRow
const friendRow = new SideNav (page).friend ("StreamFriend" );Friend row Assert
badge reads “Match”
await expect (friendRow.locators.badge).toHaveText ("Match" );Act
Open menu
await friendRow.openMenu ();Assert
menu item “Watch stream” count is 0
await expect (friendRow.menuItem ("Watch stream" )).toHaveCount (0 );Source test ("a casted match whose caster is offline is not live" , async ({
page,
factories,
}) => {
const [friend] = await createNamedUsers (factories, ["StreamFriend" ]);
await befriend (factories, [friend.id]);
const { tournament, matchId } = await createInProgressMatch (factories, {
name: "Match Tournament" ,
friendId: friend.id,
});
await factories.TournamentFactory .castMatch ({
tournamentId: tournament.id,
matchId,
twitchAccount: CAST_ACCOUNT ,
});
await impersonate (page, NZAP_TEST_ID );
await new FrontPage (page).goto ();
const friendRow = new SideNav (page).friend ("StreamFriend" );
await expect (friendRow.locators.badge).toHaveText ("Match" );
await friendRow.openMenu ();
await expect (friendRow.menuItem ("Watch stream" )).toHaveCount (0 );
})Renders/
Front page Friend row Arrange
Create named users “WaitingFriend” → [friend]
const [friend] = await createNamedUsers (factories, ["WaitingFriend" ]);Befriend friend.id
await befriend (factories, [friend.id]);Create tournament with bye team name “Waiting Tournament” waiting user id friend.id
await createTournamentWithByeTeam (factories, {
name: "Waiting Tournament" ,
waitingUserId: friend.id,
});Replace all live stream user id friend.id
await factories.LiveStreamFactory .replaceAll ([{ userId: friend.id }]);Front page Act
Open the front page
await new FrontPage (page).goto ();Side nav
Act
Friend “WaitingFriend” → friendRow
const friendRow = new SideNav (page).friend ("WaitingFriend" );Friend row Assert
badge reads “Next”
await expect (friendRow.locators.badge).toHaveText ("Next" );Act
Open menu
await friendRow.openMenu ();Assert
menu item “View tournament” is visible
await expect (friendRow.menuItem ("View tournament" )).toBeVisible ();menu item “Watch stream” count is 0
await expect (friendRow.menuItem ("Watch stream" )).toHaveCount (0 );Source test ("a friend waiting for their next match is never live" , async ({
page,
factories,
}) => {
const [friend] = await createNamedUsers (factories, ["WaitingFriend" ]);
await befriend (factories, [friend.id]);
await createTournamentWithByeTeam (factories, {
name: "Waiting Tournament" ,
waitingUserId: friend.id,
});
await factories.LiveStreamFactory .replaceAll ([{ userId: friend.id }]);
await impersonate (page, NZAP_TEST_ID );
await new FrontPage (page).goto ();
const friendRow = new SideNav (page).friend ("WaitingFriend" );
await expect (friendRow.locators.badge).toHaveText ("Next" );
await friendRow.openMenu ();
await expect (friendRow.menuItem ("View tournament" )).toBeVisible ();
await expect (friendRow.menuItem ("Watch stream" )).toHaveCount (0 );
})Renders/ /q/match/:id
Front page Friend row Front page Friend row Arrange
Create named users “MatchFriend” , “MatchStreamer” → [friend, streamer]
const [friend, streamer] = await createNamedUsers (factories, [
"MatchFriend" ,
"MatchStreamer" ,
]);Befriend friend.id
await befriend (factories, [friend.id]);Create SQ match alpha user ids friend.id, streamer.id, ...(await createUserIds (factories, 2 )) bravo user ids createUserIds (factories, 4 ) → match
const match = await factories.SQMatchFactory .create ({
alphaUserIds: [
friend.id,
streamer.id,
...(await createUserIds (factories, 2 )),
],
bravoUserIds: await createUserIds (factories, 4 ),
});Replace all live stream user id streamer.id
await factories.LiveStreamFactory .replaceAll ([{ userId: streamer.id }]);Front page Act
Open the front page
await front.goto ();Side nav
Act
Friend “MatchFriend” → friendRow
const friendRow = new SideNav (page).friend ("MatchFriend" );Friend row Assert
badge reads “Live”
await expect (friendRow.locators.badge).toHaveText ("Live" );Act
Open menu
await friendRow.openMenu ();Assert
watch stream href is twitchUrl (streamAccountOf (streamer.id))
expect (await friendRow.watchStreamHref ()).toBe (
twitchUrl (streamAccountOf (streamer.id)),
);Arrange
Replace all live stream
await factories.LiveStreamFactory .replaceAll ([]);Front page Act
Open the front page
await front.goto ();Friend row Assert
badge reads “Match”
await expect (friendRow.locators.badge).toHaveText ("Match" );Act
Open menu
await friendRow.openMenu ();Assert
menu item “Watch stream” count is 0
await expect (friendRow.menuItem ("Watch stream" )).toHaveCount (0 );Act
Click menu item “View match”
await friendRow.menuItem ("View match" ).click ();Assert
the page URL is sendouQMatchPage (match.id)
await expect (page).toHaveURL (sendouQMatchPage (match.id));no error page
await expectNoErrorPage (page);Source test ("shows the stream of a friend's SendouQ match" , async ({
page,
factories,
}) => {
const [friend, streamer] = await createNamedUsers (factories, [
"MatchFriend" ,
"MatchStreamer" ,
]);
await befriend (factories, [friend.id]);
const match = await factories.SQMatchFactory .create ({
alphaUserIds: [
friend.id,
streamer.id,
...(await createUserIds (factories, 2 )),
],
bravoUserIds: await createUserIds (factories, 4 ),
});
await factories.LiveStreamFactory .replaceAll ([{ userId: streamer.id }]);
await impersonate (page, NZAP_TEST_ID );
const front = new FrontPage (page);
await front.goto ();
const friendRow = new SideNav (page).friend ("MatchFriend" );
await expect (friendRow.locators.badge).toHaveText ("Live" );
await friendRow.openMenu ();
expect (await friendRow.watchStreamHref ()).toBe (
twitchUrl (streamAccountOf (streamer.id)),
);
await factories.LiveStreamFactory .replaceAll ([]);
await front.goto ();
await expect (friendRow.locators.badge).toHaveText ("Match" );
await friendRow.openMenu ();
await expect (friendRow.menuItem ("Watch stream" )).toHaveCount (0 );
await friendRow.menuItem ("View match" ).click ();
await expect (page).toHaveURL (sendouQMatchPage (match.id));
await expectNoErrorPage (page);
})Renders/
Front page Side nav Front page Side nav Front page Side nav Front page Act
Open the front page
await front.goto ();Side nav Act
Toggle collapse
await sideNav.toggleCollapse ();Assert
section heading “Events” count is 0
await expect (sideNav.sectionHeading ("Events" )).toHaveCount (0 );Front page Act
Open the front page
await front.goto ();Side nav Assert
section heading “Events” count is 0
await expect (sideNav.sectionHeading ("Events" )).toHaveCount (0 );Act
Toggle collapse
await sideNav.toggleCollapse ();Assert
section heading “Events” is visible
await expect (sideNav.sectionHeading ("Events" )).toBeVisible ();Front page Act
Open the front page
await front.goto ();Side nav Assert
section heading “Events” is visible
await expect (sideNav.sectionHeading ("Events" )).toBeVisible ();Source test ("collapsing the sidebar sticks across reloads" , async ({ page }) => {
await impersonate (page, NZAP_TEST_ID );
const front = new FrontPage (page);
await front.goto ();
const sideNav = new SideNav (page);
await sideNav.toggleCollapse ();
await expect (sideNav.sectionHeading ("Events" )).toHaveCount (0 );
await front.goto ();
await expect (sideNav.sectionHeading ("Events" )).toHaveCount (0 );
await sideNav.toggleCollapse ();
await expect (sideNav.sectionHeading ("Events" )).toBeVisible ();
await front.goto ();
await expect (sideNav.sectionHeading ("Events" )).toBeVisible ();
})Renders/ /u/:identifier /u/:identifier
Front page Side nav Friend row Side nav Arrange
Create named users “ModalFriend” → [friend]
const [friend] = await createNamedUsers (factories, ["ModalFriend" ]);Befriend friend.id
await befriend (factories, [friend.id]);Use a TABLET_VIEWPORT viewport
await page.setViewportSize (TABLET_VIEWPORT );Front page Act
Open the front page
await new FrontPage (page).goto ();Side nav Assert
section heading “Events” count is 0
await expect (sideNav.sectionHeading ("Events" )).toHaveCount (0 );Act
Open modal
await sideNav.openModal ();Assert
section heading “Events” is visible
await expect (sideNav.sectionHeading ("Events" )).toBeVisible ();section heading “Friends” is visible
await expect (sideNav.sectionHeading ("Friends" )).toBeVisible ();section heading “Streams” is visible
await expect (sideNav.sectionHeading ("Streams" )).toBeVisible ();trigger is visible
await expect (sideNav.friend ("ModalFriend" ).trigger).toBeVisible ();Act
Close modal
await sideNav.closeModal ();Assert
section heading “Events” count is 0
await expect (sideNav.sectionHeading ("Events" )).toHaveCount (0 );Act
Open modal
await sideNav.openModal ();Friend “ModalFriend” → friendRow
const friendRow = sideNav.friend ("ModalFriend" );Friend row Act
Open menu
await friendRow.openMenu ();Click menu item “View user page”
await friendRow.menuItem ("View user page" ).click ();Assert
the page URL is /\/u\//
await expect (page).toHaveURL (/\/u\//); Side nav Assert
section heading “Events” count is 0
await expect (sideNav.sectionHeading ("Events" )).toHaveCount (0 );no error page
await expectNoErrorPage (page);Source test ("tablet shows the same sidebar in a modal" , async ({
page,
factories,
}) => {
const [friend] = await createNamedUsers (factories, ["ModalFriend" ]);
await befriend (factories, [friend.id]);
await page.setViewportSize (TABLET_VIEWPORT );
await impersonate (page, NZAP_TEST_ID );
await new FrontPage (page).goto ();
const sideNav = new SideNav (page);
await expect (sideNav.sectionHeading ("Events" )).toHaveCount (0 );
await sideNav.openModal ();
await expect (sideNav.sectionHeading ("Events" )).toBeVisible ();
await expect (sideNav.sectionHeading ("Friends" )).toBeVisible ();
await expect (sideNav.sectionHeading ("Streams" )).toBeVisible ();
await expect (sideNav.friend ("ModalFriend" ).trigger).toBeVisible ();
await sideNav.closeModal ();
await expect (sideNav.sectionHeading ("Events" )).toHaveCount (0 );
await sideNav.openModal ();
const friendRow = sideNav.friend ("ModalFriend" );
await friendRow.openMenu ();
await friendRow.menuItem ("View user page" ).click ();
await expect (page).toHaveURL (/\/u\//);
await expect (sideNav.sectionHeading ("Events" )).toHaveCount (0 );
await expectNoErrorPage (page);
})Renders/ /events
Front page Mobile nav Friend row Mobile nav Arrange
Create named users “StreamFriend” → [friend]
const [friend] = await createNamedUsers (factories, ["StreamFriend" ]);Befriend friend.id
await befriend (factories, [friend.id]);Create in progress match name “Streamed Tournament” friend id friend.id
await createInProgressMatch (factories, {
name: "Streamed Tournament" ,
friendId: friend.id,
});Replace all live stream user id friend.id
await factories.LiveStreamFactory .replaceAll ([{ userId: friend.id }]);Create tournament author Sendou name “My Tournament” start times inHours (2 ) → tournament
const tournament = await factories.TournamentFactory .create ({
authorId: ADMIN_ID ,
name: "My Tournament" ,
startTimes: [inHours (2 )],
});Create tournament team tournament id tournament.id member user ids N-ZAP
await factories.TournamentTeamFactory .create ({
tournamentId: tournament.id,
memberUserIds: [NZAP_TEST_ID ],
});Use a MOBILE_VIEWPORT viewport
await page.setViewportSize (MOBILE_VIEWPORT );Front page Act
Open the front page
await new FrontPage (page).goto ();Mobile nav Act
Open panel “friends”
await mobileNav.openPanel ("friends" );Friend “StreamFriend” → friendRow
const friendRow = mobileNav.friend ("StreamFriend" );Friend row Assert
badge reads “Live”
await expect (friendRow.locators.badge).toHaveText ("Live" );Act
Open menu
await friendRow.openMenu ();Assert
watch stream href is twitchUrl (streamAccountOf (friend.id))
expect (await friendRow.watchStreamHref ()).toBe (
twitchUrl (streamAccountOf (friend.id)),
);Act
Press Escape
await page.keyboard.press ("Escape" );Mobile nav Act
Switch panel “tourneys”
await mobileNav.switchPanel ("tourneys" );Assert
event item “My Tournament” is visible
await expect (mobileNav.eventItem ("My Tournament" )).toBeVisible ();Act
Switch panel “menu”
await mobileNav.switchPanel ("menu" );Assert
streams heading is visible
await expect (mobileNav.locators.streamsHeading).toBeVisible ();stream item “Streamed Tournament” is visible
await expect (mobileNav.streamItem ("Streamed Tournament" )).toBeVisible ();Act
Switch panel “tourneys”
await mobileNav.switchPanel ("tourneys" );Click view all link
await mobileNav.locators.viewAllLink.click ();Assert
the page URL is EVENTS_PAGE
await expect (page).toHaveURL (EVENTS_PAGE );view all link count is 0
await expect (mobileNav.locators.viewAllLink).toHaveCount (0 );Source test ("mobile panels show the same data as the desktop sidebar" , async ({
page,
factories,
}) => {
const [friend] = await createNamedUsers (factories, ["StreamFriend" ]);
await befriend (factories, [friend.id]);
await createInProgressMatch (factories, {
name: "Streamed Tournament" ,
friendId: friend.id,
});
await factories.LiveStreamFactory .replaceAll ([{ userId: friend.id }]);
const tournament = await factories.TournamentFactory .create ({
authorId: ADMIN_ID ,
name: "My Tournament" ,
startTimes: [inHours (2 )],
});
await factories.TournamentTeamFactory .create ({
tournamentId: tournament.id,
memberUserIds: [NZAP_TEST_ID ],
});
await page.setViewportSize (MOBILE_VIEWPORT );
await impersonate (page, NZAP_TEST_ID );
await new FrontPage (page).goto ();
const mobileNav = new MobileNav (page);
await mobileNav.openPanel ("friends" );
const friendRow = mobileNav.friend ("StreamFriend" );
await expect (friendRow.locators.badge).toHaveText ("Live" );
await friendRow.openMenu ();
expect (await friendRow.watchStreamHref ()).toBe (
twitchUrl (streamAccountOf (friend.id)),
);
await page.keyboard.press ("Escape" );
await mobileNav.switchPanel ("tourneys" );
await expect (mobileNav.eventItem ("My Tournament" )).toBeVisible ();
await mobileNav.switchPanel ("menu" );
await expect (mobileNav.locators.streamsHeading).toBeVisible ();
await expect (mobileNav.streamItem ("Streamed Tournament" )).toBeVisible ();
await mobileNav.switchPanel ("tourneys" );
await mobileNav.locators.viewAllLink.click ();
await expect (page).toHaveURL (EVENTS_PAGE );
await expect (mobileNav.locators.viewAllLink).toHaveCount (0 );
})Renders/ /to/:id /to/:id/streams
Front page Side nav Tournament streams page Arrange
Create named users “TournamentStreamer” → [streamer]
const [streamer] = await createNamedUsers (factories, [
"TournamentStreamer" ,
]);Create in progress match name “Streamed Tournament” friend id streamer.id → { tournament }
const { tournament } = await createInProgressMatch (factories, {
name: "Streamed Tournament" ,
friendId: streamer.id,
});Replace all live stream user id streamer.id
await factories.LiveStreamFactory .replaceAll ([{ userId: streamer.id }]);Front page Act
Open the front page
await new FrontPage (page).goto ();Side nav Assert
item badge “Streamed Tournament” reads “LIVE”
await expect (sideNav.itemBadge ("Streamed Tournament" )).toHaveText ("LIVE" );item subtitle “Streamed Tournament” is not empty
await expect (sideNav.itemSubtitle ("Streamed Tournament" )).not.toBeEmpty ();Act
Click stream item “Streamed Tournament”
await sideNav.streamItem ("Streamed Tournament" ).click ();Assert
the page URL is tournamentStreamsPage (tournament.id)
await expect (page).toHaveURL (tournamentStreamsPage (tournament.id));Tournament streams page Assert
first streams is visible
await expect (
new TournamentStreamsPage (page).locators.streams.first (),
).toBeVisible ();Source test ("live tournament streams link to the tournament's streams page" , async ({
page,
factories,
}) => {
const [streamer] = await createNamedUsers (factories, [
"TournamentStreamer" ,
]);
const { tournament } = await createInProgressMatch (factories, {
name: "Streamed Tournament" ,
friendId: streamer.id,
});
await factories.LiveStreamFactory .replaceAll ([{ userId: streamer.id }]);
await impersonate (page, NZAP_TEST_ID );
await new FrontPage (page).goto ();
const sideNav = new SideNav (page);
await expect (sideNav.itemBadge ("Streamed Tournament" )).toHaveText ("LIVE" );
await expect (sideNav.itemSubtitle ("Streamed Tournament" )).not.toBeEmpty ();
await sideNav.streamItem ("Streamed Tournament" ).click ();
await expect (page).toHaveURL (tournamentStreamsPage (tournament.id));
await expect (
new TournamentStreamsPage (page).locators.streams.first (),
).toBeVisible ();
})Renders/
Front page Side nav Arrange
Create live X rank streamer
await createLiveXRankStreamer (factories);Front page Act
Open the front page
await new FrontPage (page).goto ();Side nav Assert
item subtitle “TopPlayer” reads String (TOP_PLAYER_XP )
await expect (sideNav.itemSubtitle ("TopPlayer" )).toHaveText (
String (TOP_PLAYER_XP ),
);stream item “TopPlayer” has “href” = twitchUrl (XRANK_TWITCH )
await expect (sideNav.streamItem ("TopPlayer" )).toHaveAttribute (
"href" ,
twitchUrl (XRANK_TWITCH ),
);Source test ("x rank streamers link straight to Twitch" , async ({
page,
factories,
}) => {
await createLiveXRankStreamer (factories);
await impersonate (page, NZAP_TEST_ID );
await new FrontPage (page).goto ();
const sideNav = new SideNav (page);
await expect (sideNav.itemSubtitle ("TopPlayer" )).toHaveText (
String (TOP_PLAYER_XP ),
);
await expect (sideNav.streamItem ("TopPlayer" )).toHaveAttribute (
"href" ,
twitchUrl (XRANK_TWITCH ),
);
})Renders/
Front page Side nav Arrange
Create live X rank streamer
await createLiveXRankStreamer (factories);Create tournament author Sendou name “Upcoming Tournament” start times inDays (2 ) tier 1
await factories.TournamentFactory .create (
{
authorId: ADMIN_ID ,
name: "Upcoming Tournament" ,
startTimes: [inDays (2 )],
},
{ tier: 1 },
);Front page Act
Open the front page
await new FrontPage (page).goto ();Assert
sideNav.streamItem ("TopPlayer" ), sideNav.locators.upcomingDivider, sideNav.streamItem ("Upcoming Tournament" ) top to bottom
await expectTopToBottom ([
sideNav.streamItem ("TopPlayer" ),
sideNav.locators.upcomingDivider,
sideNav.streamItem ("Upcoming Tournament" ),
]);Side nav Assert
item tier “Upcoming Tournament” is visible
await expect (sideNav.itemTier ("Upcoming Tournament" )).toBeVisible ();Act
Save stream “Upcoming Tournament”
await sideNav.saveStream ("Upcoming Tournament" );Assert
saved stream icon “Upcoming Tournament” is visible
await expect (sideNav.savedStreamIcon ("Upcoming Tournament" )).toBeVisible ();event item “Upcoming Tournament” count is 2
await expect (sideNav.eventItem ("Upcoming Tournament" )).toHaveCount (2 );Act
Save stream “Upcoming Tournament”
await sideNav.saveStream ("Upcoming Tournament" );Assert
saved stream icon “Upcoming Tournament” count is 0
await expect (sideNav.savedStreamIcon ("Upcoming Tournament" )).toHaveCount (0 );event item “Upcoming Tournament” count is 1
await expect (sideNav.eventItem ("Upcoming Tournament" )).toHaveCount (1 );Source test ("upcoming tournaments sit under the Upcoming divider and can be saved" , async ({
page,
factories,
}) => {
await createLiveXRankStreamer (factories);
await factories.TournamentFactory .create (
{
authorId: ADMIN_ID ,
name: "Upcoming Tournament" ,
startTimes: [inDays (2 )],
},
{ tier: 1 },
);
await impersonate (page, NZAP_TEST_ID );
await new FrontPage (page).goto ();
const sideNav = new SideNav (page);
await expectTopToBottom ([
sideNav.streamItem ("TopPlayer" ),
sideNav.locators.upcomingDivider,
sideNav.streamItem ("Upcoming Tournament" ),
]);
await expect (sideNav.itemTier ("Upcoming Tournament" )).toBeVisible ();
await sideNav.saveStream ("Upcoming Tournament" );
await expect (sideNav.savedStreamIcon ("Upcoming Tournament" )).toBeVisible ();
await expect (sideNav.eventItem ("Upcoming Tournament" )).toHaveCount (2 );
await sideNav.saveStream ("Upcoming Tournament" );
await expect (sideNav.savedStreamIcon ("Upcoming Tournament" )).toHaveCount (0 );
await expect (sideNav.eventItem ("Upcoming Tournament" )).toHaveCount (1 );
})Renders/
Front page Side nav Arrange
Create named users “HighTierStreamer” , “LowTierStreamer” , “SendouQStreamer” → [highTierStreamer, lowTierStreamer, sendouQStreamer]
const [highTierStreamer, lowTierStreamer, sendouQStreamer] =
await createNamedUsers (factories, [
"HighTierStreamer" ,
"LowTierStreamer" ,
"SendouQStreamer" ,
]);Create in progress match name “High Tier Tournament” friend id highTierStreamer.id tier 1
await createInProgressMatch (factories, {
name: "High Tier Tournament" ,
friendId: highTierStreamer.id,
tier: 1 ,
});Create in progress match name “Low Tier Tournament” friend id lowTierStreamer.id tier 3
await createInProgressMatch (factories, {
name: "Low Tier Tournament" ,
friendId: lowTierStreamer.id,
tier: 3 ,
});Create SQ match alpha user ids sendouQStreamer.id, ...(await createUserIds (factories, 3 )) bravo user ids createUserIds (factories, 4 )
await factories.SQMatchFactory .create ({
alphaUserIds: [
sendouQStreamer.id,
...(await createUserIds (factories, 3 )),
],
bravoUserIds: await createUserIds (factories, 4 ),
});Replace all live stream user id highTierStreamer.id , user id lowTierStreamer.id , user id sendouQStreamer.id
await factories.LiveStreamFactory .replaceAll ([
{ userId: highTierStreamer.id },
{ userId: lowTierStreamer.id },
{ userId: sendouQStreamer.id },
]);For each nth of 1 , 2 , 3
for (const nth of [1 , 2 , 3 ]) {
await factories.TournamentFactory .create (
{
authorId: ADMIN_ID ,
name: `Upcoming Tournament ${nth}` ,
startTimes: [inDays (1 )],
},
{ tier: 1 },
);
}Create tournament author Sendou name `Upcoming Tournament ${nth}` start times inDays (1 ) tier 1
await factories.TournamentFactory .create (
{
authorId: ADMIN_ID ,
name: `Upcoming Tournament ${nth}` ,
startTimes: [inDays (1 )],
},
{ tier: 1 },
);Front page Act
Open the front page
await new FrontPage (page).goto ();Side nav Assert
list items count is 5
await expect (sideNav.locators.listItems).toHaveCount (5 );sideNav.streamItem ("High Tier Tournament" ), sideNav.streamItem ("Low Tier Tournament" ), sideNav.locators.upcomingDivider top to bottom
await expectTopToBottom ([
sideNav.streamItem ("High Tier Tournament" ),
sideNav.streamItem ("Low Tier Tournament" ),
sideNav.locators.upcomingDivider,
]);Source test ("shows at most five streams, best first" , async ({
page,
factories,
}) => {
const [highTierStreamer, lowTierStreamer, sendouQStreamer] =
await createNamedUsers (factories, [
"HighTierStreamer" ,
"LowTierStreamer" ,
"SendouQStreamer" ,
]);
await createInProgressMatch (factories, {
name: "High Tier Tournament" ,
friendId: highTierStreamer.id,
tier: 1 ,
});
await createInProgressMatch (factories, {
name: "Low Tier Tournament" ,
friendId: lowTierStreamer.id,
tier: 3 ,
});
await factories.SQMatchFactory .create ({
alphaUserIds: [
sendouQStreamer.id,
...(await createUserIds (factories, 3 )),
],
bravoUserIds: await createUserIds (factories, 4 ),
});
await factories.LiveStreamFactory .replaceAll ([
{ userId: highTierStreamer.id },
{ userId: lowTierStreamer.id },
{ userId: sendouQStreamer.id },
]);
for (const nth of [1 , 2 , 3 ]) {
await factories.TournamentFactory .create (
{
authorId: ADMIN_ID ,
name: `Upcoming Tournament ${nth}` ,
startTimes: [inDays (1 )],
},
{ tier: 1 },
);
}
await impersonate (page, NZAP_TEST_ID );
await new FrontPage (page).goto ();
const sideNav = new SideNav (page);
await expect (sideNav.locators.listItems).toHaveCount (5 );
await expectTopToBottom ([
sideNav.streamItem ("High Tier Tournament" ),
sideNav.streamItem ("Low Tier Tournament" ),
sideNav.locators.upcomingDivider,
]);
})Renders/
Front page Side nav Front page Act
Open the front page
await new FrontPage (page).goto ();Side nav Assert
empty text NO_STREAMS_TEXT is visible
await expect (new SideNav (page).emptyText (NO_STREAMS_TEXT )).toBeVisible ();Source test ("shows an empty state without streams" , async ({ page }) => {
await impersonate (page, NZAP_TEST_ID );
await new FrontPage (page).goto ();
await expect (new SideNav (page).emptyText (NO_STREAMS_TEXT )).toBeVisible ();
})Renders/ /to/:id /to/:id/streams
Front page Side nav Arrange
Create named users “TournamentStreamer” → [streamer]
const [streamer] = await createNamedUsers (factories, [
"TournamentStreamer" ,
]);Create in progress match name “Streamed Tournament” friend id streamer.id → { tournament }
const { tournament } = await createInProgressMatch (factories, {
name: "Streamed Tournament" ,
friendId: streamer.id,
});Replace all live stream user id streamer.id
await factories.LiveStreamFactory .replaceAll ([{ userId: streamer.id }]);Front page Act
Open the front page
await new FrontPage (page).goto ();Side nav Assert
empty text NO_EVENTS_TEXT is visible
await expect (sideNav.emptyText (NO_EVENTS_TEXT )).toBeVisible ();empty text LOGGED_OUT_FRIENDS_TEXT is visible
await expect (sideNav.emptyText (LOGGED_OUT_FRIENDS_TEXT )).toBeVisible ();Act
Click stream item “Streamed Tournament”
await sideNav.streamItem ("Streamed Tournament" ).click ();Assert
the page URL is tournamentStreamsPage (tournament.id)
await expect (page).toHaveURL (tournamentStreamsPage (tournament.id));no error page
await expectNoErrorPage (page);Source test ("shows streams to logged out visitors" , async ({ page, factories }) => {
const [streamer] = await createNamedUsers (factories, [
"TournamentStreamer" ,
]);
const { tournament } = await createInProgressMatch (factories, {
name: "Streamed Tournament" ,
friendId: streamer.id,
});
await factories.LiveStreamFactory .replaceAll ([{ userId: streamer.id }]);
await new FrontPage (page).goto ();
const sideNav = new SideNav (page);
await expect (sideNav.emptyText (NO_EVENTS_TEXT )).toBeVisible ();
await expect (sideNav.emptyText (LOGGED_OUT_FRIENDS_TEXT )).toBeVisible ();
await sideNav.streamItem ("Streamed Tournament" ).click ();
await expect (page).toHaveURL (tournamentStreamsPage (tournament.id));
await expectNoErrorPage (page);
})FrontPage.gotoe2e/pages/front-page/front-page.ts:19
No JSDoc
async goto () {
await navigate ({ page: this .page, url: "/" });
}SideNav.locators.listItemse2e/pages/layout/side-nav.ts:33
this .root.locator ("a[class*='listLink']" )expectTopToBottome2e/helpers/sidebar.ts:62
export async function expectTopToBottom (rows: Locator []) {
const tops: number [] = [];
for (const row of rows) {
await expect (row).toBeVisible ();
const box = await row.boundingBox ();
invariant (box, "Visible row has no bounding box" );
tops.push (box.y);
}
expect (tops).toEqual ([...tops].sort ((a, b) => a - b));
}SideNav.itemSubtitlee2e/pages/layout/side-nav.ts:73
No JSDoc
itemSubtitle (name: string ) {
return this .eventItem (name).locator ("span[class*='listLinkSubtitle']" );
}SideNav.eventIteme2e/pages/layout/side-nav.ts:65
No JSDoc
eventItem (name: string ) {
return this .root.getByRole ("link" , { name });
}expectNoErrorPagee2e/helpers/playwright.ts:741
export async function expectNoErrorPage (page: Page ) {
await expect (page.getByTestId ("error-page" )).toHaveCount (0 );
}FrontPagee2e/pages/front-page/front-page.ts:6
SideNave2e/pages/layout/side-nav.ts:11
SideNav.viewAllLinke2e/pages/layout/side-nav.ts:52
No JSDoc
viewAllLink (section: "Events" | "Friends" ) {
return this .sectionHeading (section)
.locator ("xpath=.." )
.getByRole ("link" , { name: /View all/ });
}EventsPage.eventLinke2e/pages/calendar/events-page.ts:117
No JSDoc
eventLink (name: string ) {
return this .main.getByRole ("link" , { name });
}EventsPagee2e/pages/calendar/events-page.ts:14
SideNav.emptyTexte2e/pages/layout/side-nav.ts:59
emptyText (text: string ) {
return this .page.locator ("[class*='sideNavEmpty']:visible" , {
hasText: text,
});
}createNamedUserse2e/helpers/sidebar.ts:29
export function createNamedUsers (
factories: Factories ,
names: string [],
overrides?: { twitch?: string },
) {
return factories.UserFactory .createMany (names.length, (index) => ({
...overrides,
discordName: names[index],
}));
}befriende2e/helpers/sidebar.ts:46
No JSDoc
export function befriend (
factories: Factories ,
friendIds: number [],
userId = NZAP_TEST_ID ,
) {
return Promise .all (
friendIds.map ((friendId) =>
factories.FriendshipFactory .create ({
userOneId: userId,
userTwoId: friendId,
}),
),
);
}createSubSeekingTournamente2e/helpers/tournament.ts:316
export async function createSubSeekingTournament (
factories: Factories ,
{ name, subId }: { name: string ; subId: number },
) {
const tournament = await factories.TournamentFactory .create ({
authorId: ADMIN_ID ,
name,
startTimes: [dateToDatabaseTimestamp (addHours (new Date (), 2 ))],
});
await factories.TournamentTeamFactory .create (
{ tournamentId: tournament.id, memberUserIds: [subId] },
{ isLooking: true },
);
// … createInProgressMatche2e/helpers/tournament.ts:279
export async function createInProgressMatch (
factories: Factories ,
{
name,
friendId,
teammateId,
opponentId,
tier,
}: {
name: string ;
friendId: number ;
teammateId?: number ;
opponentId?: number ;
tier?: TournamentTierNumber ;
// … SideNav.friende2e/pages/layout/side-nav.ts:100
No JSDoc
friend (name: string ) {
return new FriendRow (this .page, this .root, name);
}FriendRow.locators.subtitlee2e/pages/layout/side-nav.ts:129
No JSDoc
this .trigger.locator ("span[class*='listLinkSubtitle']" )FriendRow.locators.badgee2e/pages/layout/side-nav.ts:130
No JSDoc
this .trigger.locator ("span[class*='listLinkBadge']" )FriendRowe2e/pages/layout/side-nav.ts:120
FriendRow.openMenue2e/pages/layout/side-nav.ts:134
No JSDoc
async openMenu () {
await this .trigger.click ();
}FriendRow.menuIteme2e/pages/layout/side-nav.ts:139
menuItem (name: string ) {
return this .page.getByRole ("menuitem" , { name });
}createTournamentWithByeTeame2e/helpers/tournament.ts:335
export async function createTournamentWithByeTeam (
factories: Factories ,
{ name, waitingUserId }: { name: string ; waitingUserId: number },
) {
const tournament = await factories.TournamentFactory .create ({
authorId: ADMIN_ID ,
name,
startTimes: startedTournamentTimes (),
});
await createTeams (factories, tournament.id, [
{ members: [waitingUserId] },
{},
{},
// … SideNav.locators.friendItemse2e/pages/layout/side-nav.ts:34
No JSDoc
this .root.locator ("button[class*='listButton']" )MobileNav.openPanele2e/pages/layout/mobile-nav.ts:53
No JSDoc
async openPanel (panel: Panel ) {
await this .tab (panel).click ();
await this .settleAnimations ();
}MobileNav.locators.friendItemse2e/pages/layout/mobile-nav.ts:40
No JSDoc
this .openPanelDialog.locator ("button[class*='listButton']" )MobileNav.locators.viewAllLinke2e/pages/layout/mobile-nav.ts:32
No JSDoc
page.getByRole ("link" , { name: "View all" , exact: true }) FriendsPage.friendButtone2e/pages/friends/friends-page.ts:56
friendButton (name: string ) {
return this .page
.getByRole ("main" )
.getByRole ("button" , { name, exact: true });
}MobileNave2e/pages/layout/mobile-nav.ts:21
SideNav.locators.unseenRequestsBadgee2e/pages/layout/side-nav.ts:28
No JSDoc
page.getByRole ("status" , {
name: /unseen friend request/,
}) SideNav.toggleCollapsee2e/pages/layout/side-nav.ts:104
No JSDoc
async toggleCollapse () {
await waitForPOSTResponse (this .page, () =>
this .locators.collapseButton.click (),
);
}SideNav.collapsedRequestsBadgee2e/pages/layout/side-nav.ts:44
get collapsedRequestsBadge () {
return this .locators.collapseButton.getByRole ("status" );
} FriendsPage.gotoe2e/pages/friends/friends-page.ts:35
No JSDoc
async goto () {
await navigate ({ page: this .page, url: FRIENDS_PAGE });
}FriendsPage.acceptRequeste2e/pages/friends/friends-page.ts:49
async acceptRequest () {
await waitForPOSTResponse (this .page, () =>
this .locators.acceptButton.first ().click (),
);
}FriendsPagee2e/pages/friends/friends-page.ts:13
FriendRow.watchStreamHrefe2e/pages/layout/side-nav.ts:143
No JSDoc
watchStreamHref () {
return this .menuItem ("Watch stream" ).getAttribute ("href" );
}SideNav.sectionHeadinge2e/pages/layout/side-nav.ts:48
No JSDoc
sectionHeading (section: Section ) {
return this .root.getByRole ("heading" , { name: section });
}SideNav.openModale2e/pages/layout/side-nav.ts:110
No JSDoc
async openModal () {
await this .locators.modalTrigger.click ();
}SideNav.closeModale2e/pages/layout/side-nav.ts:114
No JSDoc
async closeModal () {
await this .page.keyboard.press ("Escape" );
}MobileNav.friende2e/pages/layout/mobile-nav.ts:87
No JSDoc
friend (name: string ) {
return new FriendRow (this .page, this .openPanelDialog, name);
}MobileNav.switchPanele2e/pages/layout/mobile-nav.ts:59
async switchPanel (panel: Panel ) {
await this .tab (panel).click ();
await this .settleAnimations ();
}MobileNav.eventIteme2e/pages/layout/mobile-nav.ts:91
No JSDoc
eventItem (name: string ) {
return this .openPanelDialog.getByRole ("link" , { name });
}MobileNav.locators.streamsHeadinge2e/pages/layout/mobile-nav.ts:31
No JSDoc
page.locator ("h3" ).filter ({ hasText: "Streams" }) MobileNav.streamIteme2e/pages/layout/mobile-nav.ts:95
No JSDoc
streamItem (name: string ) {
return this .eventItem (name);
}SideNav.itemBadgee2e/pages/layout/side-nav.ts:77
No JSDoc
itemBadge (name: string ) {
return this .eventItem (name).locator ("span[class*='listLinkBadge']" );
}SideNav.streamIteme2e/pages/layout/side-nav.ts:69
No JSDoc
streamItem (name: string ) {
return this .eventItem (name);
}TournamentStreamsPage.locators.streamse2e/pages/tournament/tournament-streams-page.ts:13
No JSDoc
page.getByTestId ("tournament-stream" ) TournamentStreamsPagee2e/pages/tournament/tournament-streams-page.ts:6
createLiveXRankStreamere2e/sidebar-streams.spec.ts:199
No JSDoc
async function createLiveXRankStreamer (factories: Factories ) {
const [topPlayer] = await createNamedUsers (factories, ["TopPlayer" ], {
twitch: XRANK_TWITCH ,
});
await factories.XRankPlacementFactory .create (
{ playerUserId: topPlayer.id, power: TOP_PLAYER_XP },
{ refreshPeakXp: true },
);
await factories.SkillFactory .create (
{ userId: topPlayer.id, season: Seasons .currentOrPrevious ()!.nth },
{ matchesCount: MATCHES_COUNT_NEEDED_FOR_LEADERBOARD },
);
await factories.LiveStreamFactory .replaceAll ([
{ userId: topPlayer.id, account: XRANK_TWITCH },
// … SideNav.itemTiere2e/pages/layout/side-nav.ts:82
itemTier (name: string ) {
return this .streamItem (name).getByTestId ("confirmed-tier" );
}SideNav.saveStreame2e/pages/layout/side-nav.ts:94
No JSDoc
async saveStream (streamName: string ) {
await waitForPOSTResponse (this .page, () =>
this .saveStreamButton (streamName).click (),
);
}SideNav.savedStreamIcone2e/pages/layout/side-nav.ts:90
No JSDoc
savedStreamIcon (streamName: string ) {
return this .streamItem (streamName).locator ("svg.lucide-bookmark-check" );
}