tests: remove more testcafe .find() calls (#376)
This commit is contained in:
		
							parent
							
								
									fa08739fc4
								
							
						
					
					
						commit
						e489702dc6
					
				
					 10 changed files with 69 additions and 58 deletions
				
			
		|  | @ -1,5 +1,6 @@ | |||
| import { getNthStatus } from '../utils' | ||||
| import { getNthStatus, getNthStatusSelector } from '../utils' | ||||
| import { loginAsFoobar } from '../roles' | ||||
| import { Selector as $ } from 'testcafe' | ||||
| 
 | ||||
| fixture`005-status-types.js` | ||||
|   .page`http://localhost:4002` | ||||
|  | @ -8,20 +9,20 @@ test('shows direct vs followers-only vs regular', async t => { | |||
|   await loginAsFoobar(t) | ||||
|   await t | ||||
|     .expect(getNthStatus(1).getAttribute('aria-label')).eql('Status by admin') | ||||
|     .expect(getNthStatus(1).find('.status-content').innerText).contains('notification of unlisted message') | ||||
|     .expect(getNthStatus(1).find('.status-toolbar button:nth-child(2)').getAttribute('aria-label')) | ||||
|     .expect($(`${getNthStatusSelector(1)} .status-content`).innerText).contains('notification of unlisted message') | ||||
|     .expect($(`${getNthStatusSelector(1)} .status-toolbar button:nth-child(2)`).getAttribute('aria-label')) | ||||
|     .eql('Boost') | ||||
|     .expect(getNthStatus(1).find('.status-toolbar button:nth-child(2)').hasAttribute('disabled')).notOk() | ||||
|     .expect($(`${getNthStatusSelector(1)} .status-toolbar button:nth-child(2)`).hasAttribute('disabled')).notOk() | ||||
|     .expect(getNthStatus(2).getAttribute('aria-label')).eql('Status by admin') | ||||
|     .expect(getNthStatus(2).find('.status-content').innerText).contains('notification of followers-only message') | ||||
|     .expect(getNthStatus(2).find('.status-toolbar button:nth-child(2)').getAttribute('aria-label')) | ||||
|     .expect($(`${getNthStatusSelector(2)} .status-content`).innerText).contains('notification of followers-only message') | ||||
|     .expect($(`${getNthStatusSelector(2)} .status-toolbar button:nth-child(2)`).getAttribute('aria-label')) | ||||
|     .eql('Cannot be boosted because this is followers-only') | ||||
|     .expect(getNthStatus(2).find('.status-toolbar button:nth-child(2)').hasAttribute('disabled')).ok() | ||||
|     .expect($(`${getNthStatusSelector(2)} .status-toolbar button:nth-child(2)`).hasAttribute('disabled')).ok() | ||||
|     .expect(getNthStatus(3).getAttribute('aria-label')).eql('Direct message by admin') | ||||
|     .expect(getNthStatus(3).find('.status-content').innerText).contains('notification of direct message') | ||||
|     .expect(getNthStatus(3).find('.status-toolbar button:nth-child(2)').getAttribute('aria-label')) | ||||
|     .expect($(`${getNthStatusSelector(3)} .status-content`).innerText).contains('notification of direct message') | ||||
|     .expect($(`${getNthStatusSelector(3)} .status-toolbar button:nth-child(2)`).getAttribute('aria-label')) | ||||
|     .eql('Cannot be boosted because this is a direct message') | ||||
|     .expect(getNthStatus(3).find('.status-toolbar button:nth-child(2)').hasAttribute('disabled')).ok() | ||||
|     .expect($(`${getNthStatusSelector(3)} .status-toolbar button:nth-child(2)`).hasAttribute('disabled')).ok() | ||||
| }) | ||||
| 
 | ||||
| test('shows direct vs followers-only vs regular in notifications', async t => { | ||||
|  | @ -29,18 +30,18 @@ test('shows direct vs followers-only vs regular in notifications', async t => { | |||
|   await t | ||||
|     .navigateTo('/notifications') | ||||
|     .expect(getNthStatus(2).getAttribute('aria-label')).eql('Status by admin') | ||||
|     .expect(getNthStatus(2).find('.status-content').innerText).contains('notification of unlisted message') | ||||
|     .expect(getNthStatus(2).find('.status-toolbar button:nth-child(2)').getAttribute('aria-label')) | ||||
|     .expect($(`${getNthStatusSelector(2)} .status-content`).innerText).contains('notification of unlisted message') | ||||
|     .expect($(`${getNthStatusSelector(2)} .status-toolbar button:nth-child(2)`).getAttribute('aria-label')) | ||||
|     .eql('Boost') | ||||
|     .expect(getNthStatus(2).find('.status-toolbar button:nth-child(2)').hasAttribute('disabled')).notOk() | ||||
|     .expect($(`${getNthStatusSelector(2)} .status-toolbar button:nth-child(2)`).hasAttribute('disabled')).notOk() | ||||
|     .expect(getNthStatus(3).getAttribute('aria-label')).eql('Status by admin') | ||||
|     .expect(getNthStatus(3).find('.status-content').innerText).contains('notification of followers-only message') | ||||
|     .expect(getNthStatus(3).find('.status-toolbar button:nth-child(2)').getAttribute('aria-label')) | ||||
|     .expect($(`${getNthStatusSelector(3)} .status-content`).innerText).contains('notification of followers-only message') | ||||
|     .expect($(`${getNthStatusSelector(3)} .status-toolbar button:nth-child(2)`).getAttribute('aria-label')) | ||||
|     .eql('Cannot be boosted because this is followers-only') | ||||
|     .expect(getNthStatus(3).find('.status-toolbar button:nth-child(2)').hasAttribute('disabled')).ok() | ||||
|     .expect($(`${getNthStatusSelector(3)} .status-toolbar button:nth-child(2)`).hasAttribute('disabled')).ok() | ||||
|     .expect(getNthStatus(4).getAttribute('aria-label')).eql('Direct message by admin') | ||||
|     .expect(getNthStatus(4).find('.status-content').innerText).contains('notification of direct message') | ||||
|     .expect(getNthStatus(4).find('.status-toolbar button:nth-child(2)').getAttribute('aria-label')) | ||||
|     .expect($(`${getNthStatusSelector(4)} .status-content`).innerText).contains('notification of direct message') | ||||
|     .expect($(`${getNthStatusSelector(4)} .status-toolbar button:nth-child(2)`).getAttribute('aria-label')) | ||||
|     .eql('Cannot be boosted because this is a direct message') | ||||
|     .expect(getNthStatus(4).find('.status-toolbar button:nth-child(2)').hasAttribute('disabled')).ok() | ||||
|     .expect($(`${getNthStatusSelector(4)} .status-toolbar button:nth-child(2)`).hasAttribute('disabled')).ok() | ||||
| }) | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| import { closeDialogButton, getNthStatus, modalDialogContents, scrollToStatus } from '../utils' | ||||
| import { closeDialogButton, getNthStatus, getNthStatusSelector, modalDialogContents, scrollToStatus } from '../utils' | ||||
| import { loginAsFoobar } from '../roles' | ||||
| import { Selector as $ } from 'testcafe' | ||||
| 
 | ||||
| fixture`008-status-media.js` | ||||
|   .page`http://localhost:4002` | ||||
|  | @ -7,27 +8,27 @@ fixture`008-status-media.js` | |||
| test('shows sensitive images and videos', async t => { | ||||
|   await loginAsFoobar(t) | ||||
|   await scrollToStatus(t, 7) | ||||
|   await t.expect(getNthStatus(7).find('.status-media img').exists).notOk() | ||||
|     .click(getNthStatus(7).find('.status-sensitive-media-button')) | ||||
|     .expect(getNthStatus(7).find('.status-media img').getAttribute('alt')).eql('kitten') | ||||
|     .expect(getNthStatus(7).find('.status-media img').hasAttribute('src')).ok() | ||||
|   await t.expect($(`${getNthStatusSelector(7)} .status-media img`).exists).notOk() | ||||
|     .click($(`${getNthStatusSelector(7)} .status-sensitive-media-button`)) | ||||
|     .expect($(`${getNthStatusSelector(7)} .status-media img`).getAttribute('alt')).eql('kitten') | ||||
|     .expect($(`${getNthStatusSelector(7)} .status-media img`).hasAttribute('src')).ok() | ||||
|     .hover(getNthStatus(8)) | ||||
|     .expect(getNthStatus(8).find('.status-media .play-video-button').exists).notOk() | ||||
|     .click(getNthStatus(8).find('.status-sensitive-media-button')) | ||||
|     .expect(getNthStatus(8).find('.status-media .play-video-button').exists).ok() | ||||
|     .expect($(`${getNthStatusSelector(8)} .status-media .play-video-button`).exists).notOk() | ||||
|     .click($(`${getNthStatusSelector(8)} .status-sensitive-media-button`)) | ||||
|     .expect($(`${getNthStatusSelector(8)} .status-media .play-video-button`).exists).ok() | ||||
| }) | ||||
| 
 | ||||
| test('click and close image and video modals', async t => { | ||||
|   await loginAsFoobar(t) | ||||
|   await scrollToStatus(t, 9) | ||||
|   await t.expect(modalDialogContents.exists).notOk() | ||||
|     .click(getNthStatus(9).find('.play-video-button')) | ||||
|     .click($(`${getNthStatusSelector(9)} .play-video-button`)) | ||||
|     .expect(modalDialogContents.exists).ok() | ||||
|     .click(closeDialogButton) | ||||
|     .expect(modalDialogContents.exists).notOk() | ||||
|     .hover(getNthStatus(11)) | ||||
|     .hover(getNthStatus(12)) | ||||
|     .click(getNthStatus(12).find('.show-image-button')) | ||||
|     .click($(`${getNthStatusSelector(12)} .show-image-button`)) | ||||
|     .expect(modalDialogContents.exists).ok() | ||||
|     .click(closeDialogButton) | ||||
|     .expect(modalDialogContents.exists).notOk() | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ import { | |||
|   getNthStatusSelector | ||||
| } from '../utils' | ||||
| import { loginAsFoobar } from '../roles' | ||||
| import { Selector as $ } from 'testcafe' | ||||
| 
 | ||||
| fixture`010-focus.js` | ||||
|   .page`http://localhost:4002` | ||||
|  | @ -12,9 +13,9 @@ test('modal preserves focus', async t => { | |||
|   await loginAsFoobar(t) | ||||
|   await scrollToStatus(t, 9) | ||||
|   // explicitly hover-focus-click
 | ||||
|   await t.hover(getNthStatus(9).find('.play-video-button')) | ||||
|   await t.hover($(`${getNthStatusSelector(9)} .play-video-button`)) | ||||
|   await focus(`${getNthStatusSelector(9)} .play-video-button`)() | ||||
|   await t.click(getNthStatus(9).find('.play-video-button')) | ||||
|   await t.click($(`${getNthStatusSelector(9)} .play-video-button`)) | ||||
|     .click(closeDialogButton) | ||||
|     .expect(modalDialogContents.exists).notOk() | ||||
|     .expect(getActiveElementClass()).contains('play-video-button') | ||||
|  | @ -39,13 +40,13 @@ test('timeline link preserves focus', async t => { | |||
|   await loginAsFoobar(t) | ||||
|   await t | ||||
|     .expect(getNthStatus(0).exists).ok({timeout: 20000}) | ||||
|     .click(getNthStatus(0).find('.status-header a')) | ||||
|     .click($(`${getNthStatusSelector(0)} .status-header a`)) | ||||
|     .expect(getUrl()).contains('/accounts/') | ||||
|     .click(goBackButton) | ||||
|     .expect(getUrl()).eql('http://localhost:4002/') | ||||
|     .expect(getNthStatus(0).exists).ok() | ||||
|     .expect(getActiveElementInnerText()).eql('admin') | ||||
|     .click(getNthStatus(0).find('.status-sidebar')) | ||||
|     .click($(`${getNthStatusSelector(0)} .status-sidebar`)) | ||||
|     .expect(getUrl()).contains('/accounts/') | ||||
|     .click(goBackButton) | ||||
|     .expect(getUrl()).eql('http://localhost:4002/') | ||||
|  | @ -58,7 +59,7 @@ test('notification timeline preserves focus', async t => { | |||
|   await t | ||||
|     .navigateTo('/notifications') | ||||
|   await scrollToStatus(t, 5) | ||||
|   await t.click(getNthStatus(5).find('.status-header a')) | ||||
|   await t.click($(`${getNthStatusSelector(5)} .status-header a`)) | ||||
|     .expect(getUrl()).contains('/accounts/') | ||||
|     .click(goBackButton) | ||||
|     .expect(getUrl()).eql('http://localhost:4002/notifications') | ||||
|  | @ -74,7 +75,7 @@ test('thread preserves focus', async t => { | |||
|   await scrollToStatus(t, 2) | ||||
|   await t.click(getNthStatus(2)) | ||||
|     .expect(getUrl()).contains('/statuses/') | ||||
|     .click(getNthStatus(24).find('.status-sidebar')) | ||||
|     .click($(`${getNthStatusSelector(24)} .status-sidebar`)) | ||||
|     .expect(getUrl()).contains('/accounts/') | ||||
|     .click(goBackButton) | ||||
|     .expect(getUrl()).contains('/statuses/') | ||||
|  | @ -82,9 +83,9 @@ test('thread preserves focus', async t => { | |||
|     .expect(getActiveElementClass()).contains('status-sidebar') | ||||
|     .expect(getActiveElementInsideNthStatus()).eql('24') | ||||
|     .click(getNthStatus(23)) | ||||
|     .expect(getNthStatus(23).find('.status-absolute-date').exists).ok() | ||||
|     .expect($(`${getNthStatusSelector(23)} .status-absolute-date`).exists).ok() | ||||
|   await goBack() | ||||
|   await t.expect(getNthStatus(24).find('.status-absolute-date').exists).ok() | ||||
|   await t.expect($(`${getNthStatusSelector(24)} .status-absolute-date`).exists).ok() | ||||
|     .expect(getActiveElementClass()).contains('status-article status-in-timeline') | ||||
|     .expect(getActiveElementInsideNthStatus()).eql('23') | ||||
| }) | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| import { getNthStatus, getUrl } from '../utils' | ||||
| import { getNthStatus, getNthStatusSelector, getUrl } from '../utils' | ||||
| import { loginAsFoobar } from '../roles' | ||||
| import { Selector as $ } from 'testcafe' | ||||
| 
 | ||||
|  | @ -6,11 +6,11 @@ fixture`016-external-links.js` | |||
|   .page`http://localhost:4002` | ||||
| 
 | ||||
| function getAnchor (nthStatus, nthAnchor) { | ||||
|   return getNthStatus(nthStatus).find('.status-content').find('a').nth(nthAnchor) | ||||
|   return $(`${getNthStatusSelector(nthStatus)} .status-content a`).nth(nthAnchor) | ||||
| } | ||||
| 
 | ||||
| function getAnchorInProfile (n) { | ||||
|   return $('.account-profile-note').find('a').nth(n) | ||||
|   return $('.account-profile-note a').nth(n) | ||||
| } | ||||
| 
 | ||||
| test('converts external links in statuses', async t => { | ||||
|  |  | |||
|  | @ -1,9 +1,10 @@ | |||
| import { | ||||
|   followersButton, | ||||
|   followsButton, getNthSearchResult, | ||||
|   getNthStatus, getUrl, goBack | ||||
|   getNthStatusSelector, getUrl, goBack | ||||
| } from '../utils' | ||||
| import { loginAsFoobar } from '../roles' | ||||
| import { Selector as $ } from 'testcafe' | ||||
| 
 | ||||
| fixture`021-followers-follows.js` | ||||
|   .page`http://localhost:4002` | ||||
|  | @ -11,7 +12,7 @@ fixture`021-followers-follows.js` | |||
| test('shows followers and follows', async t => { | ||||
|   await loginAsFoobar(t) | ||||
|   await t | ||||
|     .click(getNthStatus(0).find('.status-author-name')) | ||||
|     .click($(`${getNthStatusSelector(0)} .status-author-name`)) | ||||
|     .expect(getUrl()).match(/\/accounts\/3$/) | ||||
|     .expect(followsButton.getAttribute('aria-label')).eql('Follows 2') | ||||
|     .click(followsButton) | ||||
|  |  | |||
|  | @ -1,7 +1,11 @@ | |||
| import { loginAsFoobar } from '../roles' | ||||
| import { getNthStatus, getUrl, homeNavButton, notificationsNavButton, validateTimeline } from '../utils' | ||||
| import { | ||||
|   getNthStatus, getNthStatusSelector, getUrl, homeNavButton, notificationsNavButton, | ||||
|   validateTimeline | ||||
| } from '../utils' | ||||
| import { favoriteStatusAs } from '../serverActions' | ||||
| import { notifications } from '../fixtures' | ||||
| import { Selector as $ } from 'testcafe' | ||||
| 
 | ||||
| fixture`102-notifications.js` | ||||
|   .page`http://localhost:4002` | ||||
|  | @ -14,7 +18,7 @@ test('shows unread notifications', async t => { | |||
|     .hover(getNthStatus(4)) | ||||
|     .hover(getNthStatus(5)) | ||||
|     .expect(notificationsNavButton.getAttribute('aria-label')).eql('Notifications') | ||||
|   let statusId = (await getNthStatus(5).find('.status-relative-date').getAttribute('href')) | ||||
|   let statusId = (await $(`${getNthStatusSelector(5)} .status-relative-date`).getAttribute('href')) | ||||
|     .split('/').slice(-1)[0] | ||||
|   await favoriteStatusAs('admin', statusId) | ||||
|   await t | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| import { | ||||
|   composeButton, getNthStatus, scrollToStatus, modalDialog, sleep, | ||||
|   notificationsNavButton, getUrl | ||||
|   notificationsNavButton, getUrl, getNthStatusSelector | ||||
| } from '../utils' | ||||
| import { loginAsFoobar } from '../roles' | ||||
| import { Selector as $ } from 'testcafe' | ||||
|  | @ -40,5 +40,5 @@ test('can use emoji dialog within compose dialog', async t => { | |||
|     .click(notificationsNavButton) | ||||
|     .expect(getUrl()).contains('/notifications') | ||||
|     .navigateTo('/') | ||||
|   await t.expect(getNthStatus(0).find('img[alt=":blobpats:"]').exists).ok({timeout: 20000}) | ||||
|   await t.expect($(`${getNthStatusSelector(0)} img[alt=":blobpats:"]`).exists).ok({timeout: 20000}) | ||||
| }) | ||||
|  |  | |||
|  | @ -1,8 +1,9 @@ | |||
| import { | ||||
|   composeButton, composeContentWarning, composeInput, contentWarningButton, | ||||
|   getNthShowOrHideButton, getNthStatus | ||||
|   getNthShowOrHideButton, getNthStatus, getNthStatusSelector | ||||
| } from '../utils' | ||||
| import { loginAsFoobar } from '../roles' | ||||
| import { Selector as $ } from 'testcafe' | ||||
| 
 | ||||
| fixture`110-compose-content-warnings.js` | ||||
|   .page`http://localhost:4002` | ||||
|  | @ -14,9 +15,9 @@ test('content warnings are posted', async t => { | |||
|     .click(contentWarningButton) | ||||
|     .typeText(composeContentWarning, 'CW', {paste: true}) | ||||
|     .click(composeButton) | ||||
|     .expect(getNthStatus(0).find('.status-spoiler').innerText).contains('CW', {timeout: 30000}) | ||||
|     .expect($(`${getNthStatusSelector(0)} .status-spoiler`).innerText).contains('CW', {timeout: 30000}) | ||||
|     .click(getNthShowOrHideButton(0)) | ||||
|     .expect(getNthStatus(0).find('.status-content').innerText).contains('hello this is a toot') | ||||
|     .expect($(`${getNthStatusSelector(0)} .status-content`).innerText).contains('hello this is a toot') | ||||
|     .click(getNthShowOrHideButton(0)) | ||||
|     .expect(getNthStatus(0).innerText).notContains('hello this is a toot') | ||||
| }) | ||||
|  | @ -32,7 +33,7 @@ test('content warnings are not posted if removed', async t => { | |||
|     .click(composeButton) | ||||
|     .expect(getNthStatus(0).innerText).contains('hi this is another toot', {timeout: 30000}) | ||||
|     .expect(getNthStatus(0).innerText).notContains('content warning!') | ||||
|     .expect(getNthStatus(0).find('.status-content').innerText).contains('hi this is another toot') | ||||
|     .expect($(`${getNthStatusSelector(0)} .status-content`).innerText).contains('hi this is another toot') | ||||
| }) | ||||
| 
 | ||||
| test('content warnings can have emoji', async t => { | ||||
|  | @ -43,9 +44,9 @@ test('content warnings can have emoji', async t => { | |||
|     .typeText(composeContentWarning, 'can you feel the :blobpats: tonight') | ||||
|     .click(composeButton) | ||||
|     .expect(getNthStatus(0).innerText).contains('can you feel the', {timeout: 30000}) | ||||
|     .expect(getNthStatus(0).find('.status-spoiler img.status-emoji').getAttribute('alt')).eql(':blobpats:') | ||||
|     .expect($(`${getNthStatusSelector(0)} .status-spoiler img.status-emoji`).getAttribute('alt')).eql(':blobpats:') | ||||
|     .click(getNthShowOrHideButton(0)) | ||||
|     .expect(getNthStatus(0).find('.status-content img.status-emoji').getAttribute('alt')).eql(':blobnom:') | ||||
|     .expect($(`${getNthStatusSelector(0)} .status-content img.status-emoji`).getAttribute('alt')).eql(':blobnom:') | ||||
| }) | ||||
| 
 | ||||
| test('no XSS in content warnings or text', async t => { | ||||
|  | @ -57,7 +58,7 @@ test('no XSS in content warnings or text', async t => { | |||
|     .click(contentWarningButton) | ||||
|     .typeText(composeContentWarning, pwned2) | ||||
|     .click(composeButton) | ||||
|     .expect(getNthStatus(0).find('.status-spoiler').innerText).contains(pwned2) | ||||
|     .expect($(`${getNthStatusSelector(0)} .status-spoiler`).innerText).contains(pwned2) | ||||
|     .click(getNthShowOrHideButton(0)) | ||||
|     .expect(getNthStatus(0).find('.status-content').innerText).contains(pwned1) | ||||
|     .expect($(`${getNthStatusSelector(0)} .status-content`).innerText).contains(pwned1) | ||||
| }) | ||||
|  |  | |||
|  | @ -2,9 +2,10 @@ import { | |||
|   composeInput, getActiveElementClass, | ||||
|   getNthComposeReplyButton, | ||||
|   getNthComposeReplyInput, getNthReplyButton, | ||||
|   getNthStatus | ||||
|   getNthStatusSelector | ||||
| } from '../utils' | ||||
| import { loginAsFoobar } from '../roles' | ||||
| import { Selector as $ } from 'testcafe' | ||||
| 
 | ||||
| fixture`111-focus.js` | ||||
|   .page`http://localhost:4002` | ||||
|  | @ -14,7 +15,7 @@ test('replying to a toot returns focus to reply button', async t => { | |||
|   await t | ||||
|     .typeText(composeInput, 'I would like, if I may, to take you on a strange journey', {paste: true}) | ||||
|     .pressKey('ctrl+enter') | ||||
|     .expect(getNthStatus(0).find('.status-content').innerText).contains('I would like, if I may, to take you on a strange journey') | ||||
|     .expect($(`${getNthStatusSelector(0)} .status-content`).innerText).contains('I would like, if I may, to take you on a strange journey') | ||||
|     .click(getNthReplyButton(0)) | ||||
|     .typeText(getNthComposeReplyInput(0), 'How strange was it?', {paste: true}) | ||||
|     .click(getNthComposeReplyButton(0)) | ||||
|  |  | |||
|  | @ -1,9 +1,10 @@ | |||
| import { | ||||
|   composeButton, | ||||
|   composeInput, | ||||
|   getNthStatus | ||||
|   getNthStatus, getNthStatusSelector | ||||
| } from '../utils' | ||||
| import { loginAsFoobar } from '../roles' | ||||
| import { Selector as $ } from 'testcafe' | ||||
| 
 | ||||
| fixture`112-status-links.js` | ||||
|   .page`http://localhost:4002` | ||||
|  | @ -14,7 +15,7 @@ test('External links, hashtags, and mentions have correct attributes', async t = | |||
|     'and also http://example.com and https://joinmastodon.org and ' + | ||||
|     'https://mastodon.social.' | ||||
| 
 | ||||
|   const nthAnchor = n => getNthStatus(0).find('.status-content a').nth(n) | ||||
|   const nthAnchor = n => $(`${getNthStatusSelector(0)} .status-content a`).nth(n) | ||||
| 
 | ||||
|   await loginAsFoobar(t) | ||||
|   await t | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue