From ed8606d3f22f36b5d712ccddc07ad8926ace7acc Mon Sep 17 00:00:00 2001 From: BryceLTaylor Date: Fri, 19 Nov 2021 09:31:03 -0500 Subject: [PATCH 01/11] Update Chromedriver to version 96 --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index c7b139a6a..a261f430a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4655,9 +4655,9 @@ } }, "chromedriver": { - "version": "95.0.0", - "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-95.0.0.tgz", - "integrity": "sha512-HwSg7S0ZZYsHTjULwxFHrrUqEpz1+ljDudJM3eOquvqD5QKnR5pSe/GlBTY9UU2tVFRYz8bEHYC4Y8qxciQiLQ==", + "version": "96.0.0", + "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-96.0.0.tgz", + "integrity": "sha512-4g6Hn5RHGsbaBmOrJbDlz/hdVPOc22eRsbvoAAMqkZxR2NJCcddHzCw2FAQeW8lX/C7xWVz3nyDsKX3fE9lIIw==", "dev": true, "requires": { "@testim/chrome-version": "^1.0.7", diff --git a/package.json b/package.json index c081d179f..9d56df94c 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "babel-preset-es2015": "6.22.0", "babel-preset-react": "6.22.0", "bowser": "1.9.4", - "chromedriver": "95.0.0", + "chromedriver": "96.0.0", "classnames": "2.2.5", "cookie": "0.4.1", "copy-webpack-plugin": "4.6.0", From 6520a5f4341c4b8833812a1255edf40e05f021ce Mon Sep 17 00:00:00 2001 From: BryceLTaylor Date: Fri, 19 Nov 2021 09:38:23 -0500 Subject: [PATCH 02/11] Integration tests use updated Sign In function from Selenium Helpers --- test/integration/comments.test.js | 4 ++-- test/integration/my-stuff.test.js | 14 ++++---------- test/integration/selenium-helpers.js | 8 +++----- test/integration/sign-in-and-out.test.js | 2 +- test/integration/studios-page.test.js | 10 +++++----- 5 files changed, 15 insertions(+), 23 deletions(-) diff --git a/test/integration/comments.test.js b/test/integration/comments.test.js index 81b9d5626..03f35f71c 100644 --- a/test/integration/comments.test.js +++ b/test/integration/comments.test.js @@ -61,7 +61,7 @@ describe('comment tests', async () => { describe('leave comments', async () => { beforeAll(async () => { - await signIn(username1, password, driver); + await signIn(username1, password); await findByXpath('//span[contains(@class, "profile-name")]'); }); @@ -137,7 +137,7 @@ describe('comment tests', async () => { describe('second user tests', async () => { beforeAll(async () => { - await signIn(username2, password, driver); + await signIn(username2, password); await findByXpath('//span[contains(@class, "profile-name")]'); }); diff --git a/test/integration/my-stuff.test.js b/test/integration/my-stuff.test.js index 1bc650dd1..035a363b8 100644 --- a/test/integration/my-stuff.test.js +++ b/test/integration/my-stuff.test.js @@ -3,10 +3,11 @@ const SeleniumHelper = require('./selenium-helpers.js'); const { + buildDriver, clickText, - findByXpath, clickXpath, - buildDriver + findByXpath, + signIn } = new SeleniumHelper(); let username = process.env.SMOKE_USERNAME + '1'; @@ -30,14 +31,7 @@ describe('www-integration my_stuff', () => { driver = await buildDriver('www-integration my_stuff'); await driver.get(rootUrl); await driver.sleep(1000); - await clickXpath('//li[@class="link right login-item"]/a'); - let name = await findByXpath('//input[@id="frc-username-1088"]'); - await name.sendKeys(username); - let word = await findByXpath('//input[@id="frc-password-1088"]'); - await word.sendKeys(password); - await driver.sleep(500); - await clickXpath('//button[contains(@class, "button") and ' + - 'contains(@class, "submit-button") and contains(@class, "white")]'); + await signIn(username, password); await findByXpath('//span[contains(@class, "profile-name")]'); }); diff --git a/test/integration/selenium-helpers.js b/test/integration/selenium-helpers.js index fbefe1799..9d94f8698 100644 --- a/test/integration/selenium-helpers.js +++ b/test/integration/selenium-helpers.js @@ -151,15 +151,13 @@ class SeleniumHelper { } // must be used on a www page - async signIn (username, password, driver) { + async signIn (username, password) { await this.clickXpath('//li[@class="link right login-item"]/a'); let name = await this.findByXpath('//input[@id="frc-username-1088"]'); await name.sendKeys(username); let word = await this.findByXpath('//input[@id="frc-password-1088"]'); - await word.sendKeys(password); - await driver.sleep(500); - await this.clickXpath('//button[contains(@class, "button") and ' + - 'contains(@class, "submit-button") and contains(@class, "white")]'); + await word.sendKeys(password + this.getKey('ENTER')); + await this.findByXpath('//span[contains(@class, "profile-name")]'); } urlMatches (regex) { diff --git a/test/integration/sign-in-and-out.test.js b/test/integration/sign-in-and-out.test.js index 34534d052..8d8ce2129 100644 --- a/test/integration/sign-in-and-out.test.js +++ b/test/integration/sign-in-and-out.test.js @@ -77,7 +77,7 @@ describe('www-integration sign-in-and-out', () => { describe('sign out', () => { beforeEach(async () => { await driver.get(wwwURL); - await signIn(username, password, driver); + await signIn(username, password); await driver.sleep(500); }); diff --git a/test/integration/studios-page.test.js b/test/integration/studios-page.test.js index 2ca9586e2..9fb1d8da6 100644 --- a/test/integration/studios-page.test.js +++ b/test/integration/studios-page.test.js @@ -78,7 +78,7 @@ describe('studio management', () => { await driver.get(rootUrl); // create a studio for tests - await signIn(username2, password, driver); + await signIn(username2, password); await findByXpath('//span[contains(@class, "profile-name")]'); await driver.get(rateLimitCheck); await driver.get(myStuffURL); @@ -99,7 +99,7 @@ describe('studio management', () => { test('invite a curator', async () => { // sign in as user2 - await signIn(username2, password, driver); + await signIn(username2, password); await findByXpath('//span[contains(@class, "profile-name")]'); // invite user3 to curate @@ -114,7 +114,7 @@ describe('studio management', () => { test('accept curator invite', async () => { // Sign in user3 - await signIn(username3, password, driver); + await signIn(username3, password); await findByXpath('//span[contains(@class, "profile-name")]'); // accept the curator invite @@ -126,7 +126,7 @@ describe('studio management', () => { test('promote to manager', async () => { // sign in as user2 - await signIn(username2, password, driver); + await signIn(username2, password); await findByXpath('//span[contains(@class, "profile-name")]'); // for some reason the user isn't showing up without reloading the page await driver.get(curatorTab); @@ -150,7 +150,7 @@ describe('studio management', () => { test('transfer studio host', async () => { // sign in as user2 - await signIn(username2, password, driver); + await signIn(username2, password); await findByXpath('//span[contains(@class, "profile-name")]'); // for some reason the user isn't showing up without reloading the page await driver.get(curatorTab); From ec60e53be2edf45580a384de5d3bca10afb832e7 Mon Sep 17 00:00:00 2001 From: BryceLTaylor Date: Fri, 19 Nov 2021 09:43:02 -0500 Subject: [PATCH 03/11] Integration tests sign in by sending enter key --- test/integration/sign-in-and-out.test.js | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/test/integration/sign-in-and-out.test.js b/test/integration/sign-in-and-out.test.js index 8d8ce2129..d93db876a 100644 --- a/test/integration/sign-in-and-out.test.js +++ b/test/integration/sign-in-and-out.test.js @@ -3,11 +3,12 @@ const SeleniumHelper = require('./selenium-helpers.js'); const { - clickText, - findByXpath, - clickXpath, - clickButton, buildDriver, + clickButton, + clickText, + clickXpath, + findByXpath, + getKey, signIn, waitUntilVisible } = new SeleniumHelper(); @@ -108,8 +109,7 @@ describe('www-integration sign-in-and-out', () => { await driver.get(scratchr2url); await clickXpath('//li[@class="sign-in dropdown"]/span'); let name = await findByXpath('//input[@id="login_dropdown_username"]'); - await name.sendKeys(nonsenseUsername); - await clickButton('Sign in'); + await name.sendKeys(nonsenseUsername + getKey('ENTER')); // find error let error = await findByXpath('//form[@id="login"]//div[@class="error"]'); @@ -126,8 +126,7 @@ describe('www-integration sign-in-and-out', () => { let name = await findByXpath('//input[@id="login_dropdown_username"]'); await name.sendKeys(nonsenseUsername); let word = await findByXpath('//input[@name="password"]'); - await word.sendKeys(password); - await clickButton('Sign in'); + await word.sendKeys(password + getKey('ENTER')); // find error let error = await findByXpath('//form[@id="login"]//div[@class="error"]'); @@ -145,8 +144,7 @@ describe('www-integration sign-in-and-out', () => { let name = await findByXpath('//input[@id="login_dropdown_username"]'); await name.sendKeys(username); let word = await findByXpath('//input[@name="password"]'); - await word.sendKeys(nonsensePassword); - await clickButton('Sign in'); + await word.sendKeys(nonsensePassword + getKey('ENTER')); // find error let error = await findByXpath('//form[@id="login"]//div[@class="error"]'); From d899d72ef4d0bebf6920bdd3928693c6eabd09fd Mon Sep 17 00:00:00 2001 From: BryceLTaylor Date: Fri, 19 Nov 2021 09:44:43 -0500 Subject: [PATCH 04/11] integration tests use waitUntilVisible in more places --- test/integration/project-page.test.js | 7 ++++--- test/integration/sign-in-and-out.test.js | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/test/integration/project-page.test.js b/test/integration/project-page.test.js index ba70d9631..03ba37811 100644 --- a/test/integration/project-page.test.js +++ b/test/integration/project-page.test.js @@ -3,9 +3,10 @@ const SeleniumHelper = require('./selenium-helpers.js'); const { - findByXpath, + buildDriver, clickXpath, - buildDriver + findByXpath, + waitUntilVisible } = new SeleniumHelper(); let remote = process.env.SMOKE_REMOTE || false; @@ -31,7 +32,7 @@ describe('www-integration project-page signed out', () => { beforeEach(async () => { await driver.get(projectUrl); let gfOverlay = await findByXpath('//div[@class="stage-wrapper_stage-wrapper_2bejr box_box_2jjDp"]'); - await gfOverlay.isDisplayed(); + await waitUntilVisible(gfOverlay, driver); }); afterAll(async () => await driver.quit()); diff --git a/test/integration/sign-in-and-out.test.js b/test/integration/sign-in-and-out.test.js index d93db876a..648be82ac 100644 --- a/test/integration/sign-in-and-out.test.js +++ b/test/integration/sign-in-and-out.test.js @@ -113,6 +113,7 @@ describe('www-integration sign-in-and-out', () => { // find error let error = await findByXpath('//form[@id="login"]//div[@class="error"]'); + await waitUntilVisible(error, driver); let errorText = await error.getText(); await expect(errorText).toEqual('This field is required.'); }); From a3acec48fdeb5105e26c7e086732bbd48ea3f336 Mon Sep 17 00:00:00 2001 From: BryceLTaylor Date: Fri, 19 Nov 2021 09:45:44 -0500 Subject: [PATCH 05/11] Integration tests fix awaits --- test/integration/my-stuff.test.js | 2 +- test/integration/studios-page.test.js | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test/integration/my-stuff.test.js b/test/integration/my-stuff.test.js index 035a363b8..b3e4775f9 100644 --- a/test/integration/my-stuff.test.js +++ b/test/integration/my-stuff.test.js @@ -99,7 +99,7 @@ describe('www-integration my_stuff', () => { await clickXpath('//form[@id="new_studio"]/button[@type="submit"]'); let tabs = await findByXpath('//div[@class="studio-tabs"]'); let tabsVisible = await tabs.isDisplayed(); - expect(tabsVisible).toBe(true); + await expect(tabsVisible).toBe(true); }); test('New studio rate limited to five', async () =>{ diff --git a/test/integration/studios-page.test.js b/test/integration/studios-page.test.js index 9fb1d8da6..7981afe71 100644 --- a/test/integration/studios-page.test.js +++ b/test/integration/studios-page.test.js @@ -85,7 +85,7 @@ describe('studio management', () => { await clickXpath('//form[@id="new_studio"]/button[@type="submit"]'); await findByXpath('//div[@class="studio-tabs"]'); promoteStudioURL = await driver.getCurrentUrl(); - curatorTab = promoteStudioURL + 'curators'; + curatorTab = await promoteStudioURL + 'curators'; }); beforeEach(async () => { @@ -108,7 +108,7 @@ describe('studio management', () => { await clickXpath('//div[@class="studio-adder-row"]/button'); let inviteAlert = await findByXpath('//div[@class="alert-msg"]'); // the confirm alert let alertText = await inviteAlert.getText(); - let successText = `Curator invite sent to "${username3}"`; + let successText = await `Curator invite sent to "${username3}"`; await expect(alertText).toMatch(successText); }); @@ -132,9 +132,9 @@ describe('studio management', () => { await driver.get(curatorTab); // promote user3 - let user3href = '/users/' + username3; + let user3href = await '/users/' + username3; // click kebab menu on the user tile - let kebabMenuXpath = `//a[@href = "${user3href}"]/` + + let kebabMenuXpath = await `//a[@href = "${user3href}"]/` + 'following-sibling::div[@class="overflow-menu-container"]'; await clickXpath(kebabMenuXpath + '/button[@class="overflow-menu-trigger"]'); // click promote @@ -156,9 +156,9 @@ describe('studio management', () => { await driver.get(curatorTab); // open kebab menu - let user2href = '/users/' + username2; + let user2href = await '/users/' + username2; // click kebab menu on the user tile - let kebabMenuXpath = `//a[@href = "${user2href}"]/` + + let kebabMenuXpath = await `//a[@href = "${user2href}"]/` + 'following-sibling::div[@class="overflow-menu-container"]'; await clickXpath(kebabMenuXpath + '/button[@class="overflow-menu-trigger"]'); From 391c0070ba94928c2e7a98a8441f9ef21ccf5bdb Mon Sep 17 00:00:00 2001 From: BryceLTaylor Date: Fri, 19 Nov 2021 09:52:41 -0500 Subject: [PATCH 06/11] add wait to studios int. test to avoid flakyness --- test/integration/studios-page.test.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/integration/studios-page.test.js b/test/integration/studios-page.test.js index 7981afe71..a477151a9 100644 --- a/test/integration/studios-page.test.js +++ b/test/integration/studios-page.test.js @@ -128,7 +128,8 @@ describe('studio management', () => { // sign in as user2 await signIn(username2, password); await findByXpath('//span[contains(@class, "profile-name")]'); - // for some reason the user isn't showing up without reloading the page + // for some reason the user isn't showing up without waiting and reloading the page + await driver.sleep(2000); await driver.get(curatorTab); // promote user3 From 2f15e8720a805a7187083131463bce3596ed3f29 Mon Sep 17 00:00:00 2001 From: BryceLTaylor Date: Mon, 29 Nov 2021 16:35:18 -0500 Subject: [PATCH 07/11] Create Selenium Helper function loadPageUntilVisible and use in comments test. --- test/integration/comments.test.js | 12 ++++++------ test/integration/selenium-helpers.js | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/test/integration/comments.test.js b/test/integration/comments.test.js index 03f35f71c..c1d9d6347 100644 --- a/test/integration/comments.test.js +++ b/test/integration/comments.test.js @@ -3,11 +3,12 @@ import SeleniumHelper from './selenium-helpers.js'; const { - findByXpath, buildDriver, - clickXpath, clickText, + clickXpath, containsClass, + findByXpath, + loadPageUntilVisible, signIn } = new SeleniumHelper(); @@ -320,10 +321,9 @@ describe('comment tests', async () => { let postButton = await findByXpath(replyRow + '//button[@class = "button compose-post"]'); await postButton.click(); - // find reply - await driver.sleep(500); - await driver.get(studioUrl); - let postedReply = await findByXpath(`//span[contains(text(), "${studioReply}")]`); + // reload page and find reply + let replyXpath = `//span[contains(text(), "${studioReply}")]`; + let postedReply = await loadPageUntilVisible(studioUrl, replyXpath, 10); let commentVisible = await postedReply.isDisplayed(); await expect(commentVisible).toBe(true); }); diff --git a/test/integration/selenium-helpers.js b/test/integration/selenium-helpers.js index 9d94f8698..cd82a4667 100644 --- a/test/integration/selenium-helpers.js +++ b/test/integration/selenium-helpers.js @@ -30,6 +30,7 @@ class SeleniumHelper { 'getDriver', 'getLogs', 'getSauceDriver', + 'loadPageUntilVisible', 'signIn', 'urlMatches', 'waitUntilGone' @@ -201,6 +202,21 @@ class SeleniumHelper { await driver.wait(until.elementIsVisible(element)); } + async loadPageUntilVisible (url, elementXpath, maxTries) { + for (let i = 0; i < maxTries; i++){ + try { + await this.driver.get(url); + let element = await this.driver.wait(until.elementLocated( + By.xpath(elementXpath)), 200, 'could not find element within 200ms'); + // let element = await this.findByXpath(elementXpath); + return await element; + } catch (e) { + console.log('reloaded the page'); + } + } + console.log('reached max tries'); + } + } module.exports = SeleniumHelper; From 47841d7891bf23cef6979e2df74e762a4a0efed8 Mon Sep 17 00:00:00 2001 From: BryceLTaylor Date: Tue, 30 Nov 2021 09:35:49 -0500 Subject: [PATCH 08/11] Clean up loadPageUntilVisible function in Selenium Helpers --- test/integration/selenium-helpers.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/integration/selenium-helpers.js b/test/integration/selenium-helpers.js index cd82a4667..b88b73de0 100644 --- a/test/integration/selenium-helpers.js +++ b/test/integration/selenium-helpers.js @@ -208,13 +208,12 @@ class SeleniumHelper { await this.driver.get(url); let element = await this.driver.wait(until.elementLocated( By.xpath(elementXpath)), 200, 'could not find element within 200ms'); - // let element = await this.findByXpath(elementXpath); return await element; } catch (e) { - console.log('reloaded the page'); + // :) eslint-disable-line no-console } } - console.log('reached max tries'); + console.error('reached max tries looking for ' + elementXpath); // eslint-disable-line no-console } } From 02af240a7e5510062223fd828e7ec7b003c0bb4a Mon Sep 17 00:00:00 2001 From: BryceLTaylor Date: Thu, 2 Dec 2021 16:26:23 -0500 Subject: [PATCH 09/11] remove reloads from comment integration tests --- test/integration/comments.test.js | 20 ++------------------ test/integration/selenium-helpers.js | 14 -------------- 2 files changed, 2 insertions(+), 32 deletions(-) diff --git a/test/integration/comments.test.js b/test/integration/comments.test.js index c1d9d6347..915de4e4a 100644 --- a/test/integration/comments.test.js +++ b/test/integration/comments.test.js @@ -81,10 +81,6 @@ describe('comment tests', async () => { await findByXpath(`//textarea[contains(text(), "${projectComment}")]`); await clickXpath('//button[@class="button compose-post"]'); - // reload the page - await driver.sleep(5000); - await driver.get(projectUrl); - // find the comment let commentXpath = await `//div[@class="comment-bubble"]/span/span[contains(text(),` + ` "${projectComment}")]`; @@ -102,9 +98,6 @@ describe('comment tests', async () => { await commentArea.sendKeys(profileComment); await clickXpath('//div[@class="button small"]/a[contains(text(), "Post")]'); - // reload page - await driver.get(profileUrl); - // find the comment let newComment = await findByXpath(`//div[@class="comment "]/div/div[contains(text(),` + ` "${profileComment}")]`); @@ -124,10 +117,6 @@ describe('comment tests', async () => { await findByXpath(`//textarea[contains(text(), "${studioComment}")]`); await clickXpath('//button[@class="button compose-post"]'); - // reload the page - await driver.sleep(5000); - await driver.get(studioUrl); - // find the comment let commentXpath = `//div[@class="comment-bubble"]/span/span[contains(text(), "${studioComment}")]`; let postedComment = await findByXpath(commentXpath); @@ -278,9 +267,6 @@ describe('comment tests', async () => { let postButton = await findByXpath(replyRow + '//button[@class = "button compose-post"]'); await postButton.click(); - // find reply - await driver.sleep(500); - await driver.get(projectUrl); let postedReply = await findByXpath(`//span[contains(text(), "${projectReply}")]`); let commentVisible = await postedReply.isDisplayed(); await expect(commentVisible).toBe(true); @@ -299,7 +285,6 @@ describe('comment tests', async () => { // click post await clickXpath(commentXpath + '//a[contains(text(), "Post")]'); - // reload the page step has been skipped because caching causes failure // The reply wasn't findable by xpath after several attempts, but it seems // better to have this much of a test }); @@ -321,9 +306,8 @@ describe('comment tests', async () => { let postButton = await findByXpath(replyRow + '//button[@class = "button compose-post"]'); await postButton.click(); - // reload page and find reply - let replyXpath = `//span[contains(text(), "${studioReply}")]`; - let postedReply = await loadPageUntilVisible(studioUrl, replyXpath, 10); + // find reply + let postedReply = await findByXpath(`//span[contains(text(), "${studioReply}")]`); let commentVisible = await postedReply.isDisplayed(); await expect(commentVisible).toBe(true); }); diff --git a/test/integration/selenium-helpers.js b/test/integration/selenium-helpers.js index b88b73de0..5fe8ca452 100644 --- a/test/integration/selenium-helpers.js +++ b/test/integration/selenium-helpers.js @@ -202,20 +202,6 @@ class SeleniumHelper { await driver.wait(until.elementIsVisible(element)); } - async loadPageUntilVisible (url, elementXpath, maxTries) { - for (let i = 0; i < maxTries; i++){ - try { - await this.driver.get(url); - let element = await this.driver.wait(until.elementLocated( - By.xpath(elementXpath)), 200, 'could not find element within 200ms'); - return await element; - } catch (e) { - // :) eslint-disable-line no-console - } - } - console.error('reached max tries looking for ' + elementXpath); // eslint-disable-line no-console - } - } module.exports = SeleniumHelper; From 769cf953dc0a0f1d0d9efd6d2085e7e1584066c7 Mon Sep 17 00:00:00 2001 From: BryceLTaylor Date: Thu, 2 Dec 2021 16:27:54 -0500 Subject: [PATCH 10/11] remove reference to 'loadPageUntilVisible' from selenium-helpers --- test/integration/selenium-helpers.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/integration/selenium-helpers.js b/test/integration/selenium-helpers.js index 5fe8ca452..9d94f8698 100644 --- a/test/integration/selenium-helpers.js +++ b/test/integration/selenium-helpers.js @@ -30,7 +30,6 @@ class SeleniumHelper { 'getDriver', 'getLogs', 'getSauceDriver', - 'loadPageUntilVisible', 'signIn', 'urlMatches', 'waitUntilGone' From ce0f7b0665dc1a6cd69015ee6b7e1094795b7af7 Mon Sep 17 00:00:00 2001 From: BryceLTaylor Date: Thu, 2 Dec 2021 16:29:50 -0500 Subject: [PATCH 11/11] remove importing of loadPageUntilVisible from comments integration tests --- test/integration/comments.test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/integration/comments.test.js b/test/integration/comments.test.js index 915de4e4a..3181a4960 100644 --- a/test/integration/comments.test.js +++ b/test/integration/comments.test.js @@ -8,7 +8,6 @@ const { clickXpath, containsClass, findByXpath, - loadPageUntilVisible, signIn } = new SeleniumHelper();