Plus Server member suggests a user, members vote and results decide the memberships Renders/plus /plus/suggestions /plus/suggestions/comment/:tier/:userId /plus/suggestions/new /plus/voting /plus/voting/results
Plus suggestions page New suggestion page Plus suggestions page Plus suggestions page Suggestion comment page Plus suggestions page Notification popover Plus voting page Plus suggestions page Notification popover Plus suggestions page Plus voting results page Act
a long flow: runs past two thirds of the default timeout under load
Slow
test.slow (); Arrange
Grant user Sendou plus tier 1
await factories.UserFactory .grant (ADMIN_ID , { plusTier: 1 });Grant user N-ZAP plus tier 1
await factories.UserFactory .grant (NZAP_TEST_ID , { plusTier: 1 });Create user discord name “SuggestedSue” discord id “1000000000000000001” profile null → suggested
const suggested = await factories.UserFactory .create ({
discordName: SUGGESTED_NAME ,
discordId: SUGGESTED_DISCORD_ID ,
profile: null ,
});Plus suggestions page Act
Open the plus suggestions page
await suggestions.goto ();Assert
no suggestions is visible
await expect (suggestions.locators.noSuggestions).toBeVisible ();New suggestion page Act
Open the new suggestion page
await newSuggestion.goto ();Assert
heading is visible
await expect (newSuggestion.locators.heading).toBeVisible ();Act
Suggest username “SuggestedSue” comment “Great player and even better person”
await newSuggestion.suggest ({
username: SUGGESTED_NAME ,
comment: SUGGESTION_TEXT ,
});Plus suggestions page Assert
suggested user “SuggestedSue” is visible
await expect (suggestions.suggestedUser (SUGGESTED_NAME )).toBeVisible ();Act
Open comments 1
await suggestions.openComments (1 );Assert
comment “Great player and even better person” is visible
await expect (suggestions.comment (SUGGESTION_TEXT )).toBeVisible ();Act
Edit comment “Great player and even better person” , “Great player and an amazing person”
await suggestions.editComment (SUGGESTION_TEXT , EDITED_SUGGESTION_TEXT );Open comments 1
await suggestions.openComments (1 );Assert
comment “Great player and an amazing person” is visible
await expect (suggestions.comment (EDITED_SUGGESTION_TEXT )).toBeVisible ();Plus suggestions page Act
Open the plus suggestions page
await suggestions.goto ();Click comment link
await suggestions.locators.commentLink.click ();Suggestion comment page Assert
heading username “SuggestedSue” tier 1 is visible
await expect (
commentPage.heading ({ username: SUGGESTED_NAME , tier: 1 }),
).toBeVisible ();Act
Comment “Seconding, deserves the spot”
await commentPage.comment (FOLLOW_UP_COMMENT_TEXT );Plus suggestions page Act
Open comments 2
await suggestions.openComments (2 );Assert
comment “Seconding, deserves the spot” is visible
await expect (suggestions.comment (FOLLOW_UP_COMMENT_TEXT )).toBeVisible ();Act
Delete comment “Seconding, deserves the spot”
await suggestions.deleteComment (FOLLOW_UP_COMMENT_TEXT );Assert
comments summary 1 is visible
await expect (suggestions.commentsSummary (1 )).toBeVisible ();Act
Set plus voting active true
await setPlusVotingActive (page, true );Run routine “NotifyPlusServerVoting”
await runRoutine (page, "NotifyPlusServerVoting" );Open the plus suggestions page
await suggestions.goto ();Notification popover Act
Open
await notifications.open ();Open notification “Plus Server voting of season”
await notifications.openNotification ("Plus Server voting of season" );Assert
the page URL is PLUS_VOTING_PAGE
await expect (page).toHaveURL (PLUS_VOTING_PAGE );Plus voting page Assert
upvote button is visible
await expect (voting.locators.upvoteButton).toBeVisible ();Act
Upvote current
await voting.upvoteCurrent ();Upvote current
await voting.upvoteCurrent ();Submit votes
await voting.submitVotes ();Assert
voted alert is visible
await expect (voting.locators.votedAlert).toBeVisible ();Act
Set plus voting active false
await setPlusVotingActive (page, false );Open the plus voting page
await voting.goto ();Assert
voting starts info is visible
await expect (voting.locators.votingStartsInfo).toBeVisible ();Plus suggestions page Act
Open the plus suggestions page
await suggestions.goto ();Notification popover Act
Open
await notifications.open ();Assert
notification “You were suggested to +1” is visible
await expect (
notifications.notification ("You were suggested to +1" ),
).toBeVisible ();Act
Close
await notifications.close ();Plus suggestions page Act
Delete own suggestion
await suggestions.deleteOwnSuggestion ();Assert
no suggestions is visible
await expect (suggestions.locators.noSuggestions).toBeVisible ();Arrange
completedVoting = lastCompletedVoting (new Date ())
const completedVoting = lastCompletedVoting (new Date ());Create user discord name “FalterFred” discord id “1000000000000000002” profile null → failer
const failer = await factories.UserFactory .create ({
discordName: FAILER_NAME ,
discordId: FAILER_DISCORD_ID ,
profile: null ,
});Create plus suggestion author Sendou suggested id suggested.id tier 1 ...completedVoting
await factories.PlusSuggestionFactory .create ({
authorId: ADMIN_ID ,
suggestedId: suggested.id,
tier: 1 ,
...completedVoting,
});Create plus vote author Sendou voted N-ZAP score PLUS_UPVOTE
await factories.PlusVoteFactory .create ({
authorId: ADMIN_ID ,
votedId: NZAP_TEST_ID ,
score: PLUS_UPVOTE ,
});Create plus vote author Sendou voted id suggested.id score PLUS_UPVOTE
await factories.PlusVoteFactory .create ({
authorId: ADMIN_ID ,
votedId: suggested.id,
score: PLUS_UPVOTE ,
});Create plus vote author Sendou voted id failer.id score PLUS_DOWNVOTE
await factories.PlusVoteFactory .create ({
authorId: ADMIN_ID ,
votedId: failer.id,
score: PLUS_DOWNVOTE ,
});Sync tiers plus vote
await factories.PlusVoteFactory .syncTiers ();Plus voting results page Act
Open the plus voting results page
await results.goto ();Assert
heading is visible
await expect (results.locators.heading).toBeVisible ();own result tier 1 passed true is visible
await expect (results.ownResult ({ tier: 1 , passed: true })).toBeVisible ();passed heading 2 is visible
await expect (results.passedHeading (2 )).toBeVisible ();failed heading 1 is visible
await expect (results.failedHeading (1 )).toBeVisible ();user result “N-ZAP” is visible
await expect (results.userResult ("N-ZAP" )).toBeVisible ();suggested marker “SuggestedSue” is visible
await expect (results.suggestedMarker (SUGGESTED_NAME )).toBeVisible ();user result “FalterFred” is visible
await expect (results.userResult (FAILER_NAME )).toBeVisible ();Act
Get “/plus/list” , headers "Lohi token" process.env.LOHI_TOKEN ?? "salmon" → plusListResponse
const plusListResponse = await page.request.get ("/plus/list" , {
headers: { "Lohi-Token" : process.env.LOHI_TOKEN ?? "salmon" },
});Assert
plusListResponse.ok () is true
expect (plusListResponse.ok ()).toBe (true );plusList = plusListResponse.json ()
const plusList = (await plusListResponse.json ()) as {
users: Record <string , number >;
};plusList.users[SUGGESTED_DISCORD_ID ] is 1
expect (plusList.users[SUGGESTED_DISCORD_ID ]).toBe (1 );a non-suggested member who fails the vote drops one tier instead of out
plusList.users[FAILER_DISCORD_ID ] is 2
expect (plusList.users[FAILER_DISCORD_ID ]).toBe (2 );Source test ("member suggests a user, members vote and results decide the memberships" , async ({
page,
factories,
}) => {
// a long flow: runs past two thirds of the default timeout under load
test.slow ();
await factories.UserFactory .grant (ADMIN_ID , { plusTier: 1 });
await factories.UserFactory .grant (NZAP_TEST_ID , { plusTier: 1 });
const suggested = await factories.UserFactory .create ({
discordName: SUGGESTED_NAME ,
discordId: SUGGESTED_DISCORD_ID ,
profile: null ,
});
await impersonate (page);
const suggestions = new PlusSuggestionsPage (page);
await suggestions.goto ();
await expect (suggestions.locators.noSuggestions).toBeVisible ();
const newSuggestion = new NewSuggestionPage (page);
await newSuggestion.goto ();
await expect (newSuggestion.locators.heading).toBeVisible ();
await newSuggestion.suggest ({
username: SUGGESTED_NAME ,
comment: SUGGESTION_TEXT ,
});
await expect (suggestions.suggestedUser (SUGGESTED_NAME )).toBeVisible ();
await suggestions.openComments (1 );
await expect (suggestions.comment (SUGGESTION_TEXT )).toBeVisible ();
await suggestions.editComment (SUGGESTION_TEXT , EDITED_SUGGESTION_TEXT );
await suggestions.openComments (1 );
await expect (suggestions.comment (EDITED_SUGGESTION_TEXT )).toBeVisible ();
await impersonate (page, NZAP_TEST_ID );
await suggestions.goto ();
await suggestions.locators.commentLink.click ();
const commentPage = new SuggestionCommentPage (page);
await expect (
commentPage.heading ({ username: SUGGESTED_NAME , tier: 1 }),
).toBeVisible ();
await commentPage.comment (FOLLOW_UP_COMMENT_TEXT );
await suggestions.openComments (2 );
await expect (suggestions.comment (FOLLOW_UP_COMMENT_TEXT )).toBeVisible ();
await suggestions.deleteComment (FOLLOW_UP_COMMENT_TEXT );
await expect (suggestions.commentsSummary (1 )).toBeVisible ();
await setPlusVotingActive (page, true );
await runRoutine (page, "NotifyPlusServerVoting" );
await suggestions.goto ();
const notifications = new NotificationPopover (page);
await notifications.open ();
await notifications.openNotification ("Plus Server voting of season" );
await expect (page).toHaveURL (PLUS_VOTING_PAGE );
const voting = new PlusVotingPage (page);
await expect (voting.locators.upvoteButton).toBeVisible ();
await voting.upvoteCurrent ();
await voting.upvoteCurrent ();
await voting.submitVotes ();
await expect (voting.locators.votedAlert).toBeVisible ();
await setPlusVotingActive (page, false );
await voting.goto ();
await expect (voting.locators.votingStartsInfo).toBeVisible ();
await impersonate (page, suggested.id);
await suggestions.goto ();
await notifications.open ();
await expect (
notifications.notification ("You were suggested to +1" ),
).toBeVisible ();
await notifications.close ();
await suggestions.deleteOwnSuggestion ();
await expect (suggestions.locators.noSuggestions).toBeVisible ();
const completedVoting = lastCompletedVoting (new Date ());
const failer = await factories.UserFactory .create ({
discordName: FAILER_NAME ,
discordId: FAILER_DISCORD_ID ,
profile: null ,
});
await factories.PlusSuggestionFactory .create ({
authorId: ADMIN_ID ,
suggestedId: suggested.id,
tier: 1 ,
...completedVoting,
});
await factories.PlusVoteFactory .create ({
authorId: ADMIN_ID ,
votedId: NZAP_TEST_ID ,
score: PLUS_UPVOTE ,
});
await factories.PlusVoteFactory .create ({
authorId: ADMIN_ID ,
votedId: suggested.id,
score: PLUS_UPVOTE ,
});
await factories.PlusVoteFactory .create ({
authorId: ADMIN_ID ,
votedId: failer.id,
score: PLUS_DOWNVOTE ,
});
await factories.PlusVoteFactory .syncTiers ();
const results = new PlusVotingResultsPage (page);
await results.goto ();
await expect (results.locators.heading).toBeVisible ();
await expect (results.ownResult ({ tier: 1 , passed: true })).toBeVisible ();
await expect (results.passedHeading (2 )).toBeVisible ();
await expect (results.failedHeading (1 )).toBeVisible ();
await expect (results.userResult ("N-ZAP" )).toBeVisible ();
await expect (results.suggestedMarker (SUGGESTED_NAME )).toBeVisible ();
await expect (results.userResult (FAILER_NAME )).toBeVisible ();
const plusListResponse = await page.request.get ("/plus/list" , {
headers: { "Lohi-Token" : process.env.LOHI_TOKEN ?? "salmon" },
});
expect (plusListResponse.ok ()).toBe (true );
const plusList = (await plusListResponse.json ()) as {
users: Record <string , number >;
};
expect (plusList.users[SUGGESTED_DISCORD_ID ]).toBe (1 );
// a non-suggested member who fails the vote drops one tier instead of out
expect (plusList.users[FAILER_DISCORD_ID ]).toBe (2 );
})Renders/plus /plus/suggestions /plus/suggestions/comment/:tier/:userId /plus/suggestions/new /plus/voting
Plus suggestions page New suggestion page Plus suggestions page Suggestion comment page Plus voting page Arrange
Grant user Sendou plus tier 1
await factories.UserFactory .grant (ADMIN_ID , { plusTier: 1 });Create user discord name “SuggestedSue” discord id “1000000000000000001” profile null → suggested
const suggested = await factories.UserFactory .create ({
discordName: SUGGESTED_NAME ,
discordId: SUGGESTED_DISCORD_ID ,
profile: null ,
});Create plus suggestion author Sendou suggested id suggested.id tier 1 text “Great player and even better person”
await factories.PlusSuggestionFactory .create ({
authorId: ADMIN_ID ,
suggestedId: suggested.id,
tier: 1 ,
text: SUGGESTION_TEXT ,
});Plus suggestions page Act
Open the plus suggestions page
await suggestions.goto ();Assert
suggested user “SuggestedSue” is visible
await expect (suggestions.suggestedUser (SUGGESTED_NAME )).toBeVisible ();comment link is not visible
await isNotVisible (suggestions.locators.commentLink);New suggestion page Act
Open the new suggestion page
await newSuggestion.goto ();Plus suggestions page Assert
no permissions alert is visible
await expect (suggestions.locators.noPermissionsAlert).toBeVisible ();heading is not visible
await isNotVisible (newSuggestion.locators.heading);Suggestion comment page Act
Open the suggestion comment page tier 1 user id suggested.id
await commentPage.goto ({ tier: 1 , userId: suggested.id });Assert
the page URL is not /comment/
await expect (page).not.toHaveURL (/comment/);heading username “SuggestedSue” tier 1 is not visible
await isNotVisible (
commentPage.heading ({ username: SUGGESTED_NAME , tier: 1 }),
);Act
Set plus voting active true
await setPlusVotingActive (page, true );Plus voting page Act
Open the plus voting page
await voting.goto ();Assert
voting ongoing info is visible
await expect (voting.locators.votingOngoingInfo).toBeVisible ();upvote button is not visible
await isNotVisible (voting.locators.upvoteButton);Source test ("user without a plus tier cannot suggest, comment or vote" , async ({
page,
factories,
}) => {
await factories.UserFactory .grant (ADMIN_ID , { plusTier: 1 });
const suggested = await factories.UserFactory .create ({
discordName: SUGGESTED_NAME ,
discordId: SUGGESTED_DISCORD_ID ,
profile: null ,
});
await factories.PlusSuggestionFactory .create ({
authorId: ADMIN_ID ,
suggestedId: suggested.id,
tier: 1 ,
text: SUGGESTION_TEXT ,
});
await impersonate (page, NZAP_TEST_ID );
const suggestions = new PlusSuggestionsPage (page);
await suggestions.goto ();
await expect (suggestions.suggestedUser (SUGGESTED_NAME )).toBeVisible ();
await isNotVisible (suggestions.locators.commentLink);
const newSuggestion = new NewSuggestionPage (page);
await newSuggestion.goto ();
await expect (suggestions.locators.noPermissionsAlert).toBeVisible ();
await isNotVisible (newSuggestion.locators.heading);
const commentPage = new SuggestionCommentPage (page);
await commentPage.goto ({ tier: 1 , userId: suggested.id });
await expect (page).not.toHaveURL (/comment/);
await isNotVisible (
commentPage.heading ({ username: SUGGESTED_NAME , tier: 1 }),
);
await setPlusVotingActive (page, true );
const voting = new PlusVotingPage (page);
await voting.goto ();
await expect (voting.locators.votingOngoingInfo).toBeVisible ();
await isNotVisible (voting.locators.upvoteButton);
})votes with the S and K keys, but not while using global search Renders/plus /plus/voting
Plus voting page Global search dialog Plus voting page Arrange
Grant user Sendou plus tier 1
await factories.UserFactory .grant (ADMIN_ID , { plusTier: 1 });Grant user N-ZAP plus tier 1
await factories.UserFactory .grant (NZAP_TEST_ID , { plusTier: 1 });For each user of factories.UserFactory .createMany (2 )
for (const user of await factories.UserFactory .createMany (2 )) {
await factories.UserFactory .grant (user.id, { plusTier: 1 });
}Grant user user.id plus tier 1
await factories.UserFactory .grant (user.id, { plusTier: 1 });Act
Set plus voting active true
await setPlusVotingActive (page, true );Plus voting page Act
Open the plus voting page
await voting.goto ();Assert
progress voted 0 total 3 is visible
await expect (voting.progress ({ voted: 0 , total: 3 })).toBeVisible ();Act
Vote with key “upvote”
await voting.voteWithKey ("upvote" );Assert
progress voted 1 total 3 is visible
await expect (voting.progress ({ voted: 1 , total: 3 })).toBeVisible ();Global search dialog Act
Open with shortcut
await search.openWithShortcut ();Type “sk”
await search.type ("sk" );Assert
input has value “sk”
await expect (search.locators.input).toHaveValue ("sk" );Act
Close
await search.close ();Plus voting page Assert
progress voted 1 total 3 is visible
await expect (voting.progress ({ voted: 1 , total: 3 })).toBeVisible ();Act
Vote with key “downvote”
await voting.voteWithKey ("downvote" );Assert
progress voted 2 total 3 is visible
await expect (voting.progress ({ voted: 2 , total: 3 })).toBeVisible ();Source test ("votes with the S and K keys, but not while using global search" , async ({
page,
factories,
}) => {
await factories.UserFactory .grant (ADMIN_ID , { plusTier: 1 });
await factories.UserFactory .grant (NZAP_TEST_ID , { plusTier: 1 });
for (const user of await factories.UserFactory .createMany (2 )) {
await factories.UserFactory .grant (user.id, { plusTier: 1 });
}
await impersonate (page);
await setPlusVotingActive (page, true );
const voting = new PlusVotingPage (page);
await voting.goto ();
await expect (voting.progress ({ voted: 0 , total: 3 })).toBeVisible ();
await voting.voteWithKey ("upvote" );
await expect (voting.progress ({ voted: 1 , total: 3 })).toBeVisible ();
const search = new GlobalSearchDialog (page);
await search.openWithShortcut ();
await search.type ("sk" );
await expect (search.locators.input).toHaveValue ("sk" );
await search.close ();
await expect (voting.progress ({ voted: 1 , total: 3 })).toBeVisible ();
await voting.voteWithKey ("downvote" );
await expect (voting.progress ({ voted: 2 , total: 3 })).toBeVisible ();
})PlusSuggestionsPage.gotoe2e/pages/plus/suggestions-page.ts:33
No JSDoc
async goto (tier?: number ) {
await navigate ({ page: this .page, url: plusSuggestionPage ({ tier }) });
}PlusSuggestionsPage.locators.noSuggestionse2e/pages/plus/suggestions-page.ts:20
No JSDoc
page.getByText ("No suggestions yet" ) NewSuggestionPage.gotoe2e/pages/plus/new-suggestion-page.ts:21
No JSDoc
async goto () {
await navigate ({ page: this .page, url: plusSuggestionsNewPage () });
}NewSuggestionPage.locators.headinge2e/pages/plus/new-suggestion-page.ts:17
No JSDoc
page.getByRole ("heading" , { name: "Adding a new suggestion" }) NewSuggestionPage.suggeste2e/pages/plus/new-suggestion-page.ts:25
No JSDoc
async suggest ({ username, comment }: { username: string ; comment: string }) {
await this .form.selectUser ("userId" , username);
await this .form.fill ("comment" , comment);
await submit (this .page);
}PlusSuggestionsPage.suggestedUsere2e/pages/plus/suggestions-page.ts:37
No JSDoc
suggestedUser (username: string ) {
return this .page.getByRole ("heading" , { name: username });
}PlusSuggestionsPage.openCommentse2e/pages/plus/suggestions-page.ts:45
No JSDoc
async openComments (count: number ) {
const details = this .page
.locator ("details" )
.filter ({ has: this .commentsSummary (count) });
if ((await details.getAttribute ("open" )) === null ) {
await this .commentsSummary (count).click ();
}
}PlusSuggestionsPage.commente2e/pages/plus/suggestions-page.ts:54
No JSDoc
comment (text: string ) {
return this .page.locator ("fieldset" ).filter ({ hasText: text });
}PlusSuggestionsPage.editCommente2e/pages/plus/suggestions-page.ts:58
No JSDoc
async editComment (currentText: string , newText: string ) {
await this .comment (currentText).getByLabel ("Edit" ).click ();
await this .editForm.fill ("comment" , newText);
await submit (this .page);
}PlusSuggestionsPage.locators.commentLinke2e/pages/plus/suggestions-page.ts:24
No JSDoc
page.getByRole ("link" , { name: "Comment" , exact: true }) SuggestionCommentPage.headinge2e/pages/plus/suggestion-comment-page.ts:24
No JSDoc
heading ({ username, tier }: { username: string ; tier: number }) {
return this .page.getByRole ("heading" , {
name: `${username}'s +${tier} suggestion` ,
});
}SuggestionCommentPage.commente2e/pages/plus/suggestion-comment-page.ts:30
No JSDoc
async comment (text: string ) {
await this .form.fill ("comment" , text);
await submit (this .page);
}PlusSuggestionsPage.deleteCommente2e/pages/plus/suggestions-page.ts:64
No JSDoc
async deleteComment (text: string ) {
await this .comment (text).getByLabel ("Delete comment" ).click ();
await modalClickConfirmButton (this .page);
}PlusSuggestionsPage.commentsSummarye2e/pages/plus/suggestions-page.ts:41
No JSDoc
commentsSummary (count: number ) {
return this .page.getByText (`Comments (${count})` );
}setPlusVotingActivee2e/helpers/playwright.ts:485
export async function setPlusVotingActive (page: Page , active: boolean ) {
const response = await retryPost (page, "/set-plus-voting-active" , {
form: { active: String (active) },
});
if (!response?.ok ()) {
throw new Error (
`Setting plus voting active failed with status ${response?.status()}` ,
);
}
}runRoutinee2e/helpers/playwright.ts:497
export async function runRoutine (page: Page , name: string ) {
const response = await retryPost (page, "/run-routine" , {
form: { name },
});
if (!response?.ok ()) {
throw new Error (
`Running routine ${name} failed with status ${response?.status()}` ,
);
}
}NotificationPopover.opene2e/pages/layout/notification-popover.ts:37
No JSDoc
async open () {
// the popover is closed on navigation, which would also close one opened
// after a click on a notification navigated but before the page rendered
await waitForNavigationRendered (this .page);
await expect (this .locators.shownPopover).toHaveCount (0 );
await this .locators.openButton.click ();
await expect (this .locators.shownPopover).toHaveCount (1 );
}NotificationPopover.openNotificatione2e/pages/layout/notification-popover.ts:54
No JSDoc
async openNotification (text: string ) {
await this .notification (text).click ();
}PlusVotingPage.locators.upvoteButtone2e/pages/plus/voting-page.ts:12
No JSDoc
page.getByRole ("button" , { name: "+1" , exact: true }) PlusVotingPage.upvoteCurrente2e/pages/plus/voting-page.ts:28
No JSDoc
async upvoteCurrent () {
await this .locators.upvoteButton.click ();
}PlusVotingPage.submitVotese2e/pages/plus/voting-page.ts:37
No JSDoc
async submitVotes () {
await submit (this .page, this .locators.submitVotesButton);
}PlusVotingPage.locators.votedAlerte2e/pages/plus/voting-page.ts:14
No JSDoc
page.getByText ("You have voted" ) PlusVotingPage.gotoe2e/pages/plus/voting-page.ts:20
No JSDoc
async goto () {
await navigate ({ page: this .page, url: PLUS_VOTING_PAGE });
}PlusVotingPage.locators.votingStartsInfoe2e/pages/plus/voting-page.ts:15
No JSDoc
page.getByText ("Next voting starts" ) NotificationPopover.notificatione2e/pages/layout/notification-popover.ts:50
No JSDoc
notification (text: string ) {
return this .locators.items.filter ({ hasText: text });
}NotificationPopover.closee2e/pages/layout/notification-popover.ts:46
No JSDoc
async close () {
await this .page.keyboard.press ("Escape" );
}PlusSuggestionsPage.deleteOwnSuggestione2e/pages/plus/suggestions-page.ts:69
No JSDoc
async deleteOwnSuggestion () {
await this .locators.deleteOwnSuggestionButton.click ();
await modalClickConfirmButton (this .page);
}PlusVotingResultsPage.gotoe2e/pages/plus/voting-results-page.ts:16
No JSDoc
async goto () {
await navigate ({ page: this .page, url: `${PLUS_VOTING_PAGE}/results` });
}PlusVotingResultsPage.locators.headinge2e/pages/plus/voting-results-page.ts:12
No JSDoc
page.getByRole ("heading" , { name: /Voting results for / }) PlusVotingResultsPage.ownResulte2e/pages/plus/voting-results-page.ts:41
ownResult ({ tier, passed }: { tier: number ; passed: boolean }) {
return this .page.locator ("li" ).filter ({
hasText: `You ${passed ? "passed" : "didn't pass"} the +${tier} voting` ,
});
}PlusVotingResultsPage.passedHeadinge2e/pages/plus/voting-results-page.ts:20
No JSDoc
passedHeading (count: number ) {
return this .page.getByRole ("heading" , { name: `Passed (${count})` });
}PlusVotingResultsPage.failedHeadinge2e/pages/plus/voting-results-page.ts:24
No JSDoc
failedHeading (count: number ) {
return this .page.getByRole ("heading" , { name: `Didn't pass (${count})` });
}PlusVotingResultsPage.userResulte2e/pages/plus/voting-results-page.ts:28
No JSDoc
userResult (username: string ) {
return this .page
.getByRole ("main" )
.getByRole ("link" , { name: username })
.first ();
}PlusVotingResultsPage.suggestedMarkere2e/pages/plus/voting-results-page.ts:36
suggestedMarker (username: string ) {
return this .userResult (username).getByText ("S" , { exact: true });
}PlusSuggestionsPagee2e/pages/plus/suggestions-page.ts:11
No JSDoc
NewSuggestionPagee2e/pages/plus/new-suggestion-page.ts:8
SuggestionCommentPagee2e/pages/plus/suggestion-comment-page.ts:8
NotificationPopovere2e/pages/layout/notification-popover.ts:6
PlusVotingPagee2e/pages/plus/voting-page.ts:5
No JSDoc
PlusVotingResultsPagee2e/pages/plus/voting-results-page.ts:5
No JSDoc
isNotVisiblee2e/helpers/playwright.ts:745
No JSDoc
export function isNotVisible (locator: Locator ) {
return expect (locator).toHaveCount (0 );
}PlusSuggestionsPage.locators.noPermissionsAlerte2e/pages/plus/suggestions-page.ts:21
No JSDoc
page.getByText (
"You do not have permissions to suggest or suggesting is not possible right now" ,
) SuggestionCommentPage.gotoe2e/pages/plus/suggestion-comment-page.ts:17
No JSDoc
async goto ({ tier, userId }: { tier: number ; userId: number }) {
await navigate ({
page: this .page,
url: plusSuggestionCommentPage ({ tier, userId }),
});
}PlusVotingPage.locators.votingOngoingInfoe2e/pages/plus/voting-page.ts:16
No JSDoc
page.getByText ("Voting is currently happening" ) PlusVotingPage.progresse2e/pages/plus/voting-page.ts:24
No JSDoc
progress ({ voted, total }: { voted: number ; total: number }) {
return this .page.getByTitle (`Voting progress ${voted} out of ${total}` );
}PlusVotingPage.voteWithKeye2e/pages/plus/voting-page.ts:33
async voteWithKey (type : "upvote" | "downvote" ) {
await this .page.keyboard.press (type === "upvote" ? "k" : "s" );
}GlobalSearchDialog.openWithShortcute2e/pages/search/global-search-dialog.ts:35
async openWithShortcut () {
await this .page.keyboard.press ("Control+k" );
await this .locators.dialog.waitFor ({ state: "visible" });
}GlobalSearchDialog.typee2e/pages/search/global-search-dialog.ts:57
async type (query: string ) {
await this .locators.input.pressSequentially (query);
}GlobalSearchDialog.locators.inpute2e/pages/search/global-search-dialog.ts:21
No JSDoc
page.getByPlaceholder ("Search..." ) GlobalSearchDialog.closee2e/pages/search/global-search-dialog.ts:40
No JSDoc
async close () {
// Escape on a filled search input clears it instead of closing the dialog
await this .locators.input.clear ();
await this .page.keyboard.press ("Escape" );
await this .locators.dialog.waitFor ({ state: "hidden" });
}GlobalSearchDialoge2e/pages/search/global-search-dialog.ts:11
No JSDoc