Merge pull request #6351 from BryceLTaylor/fix-flaky-comments-tests

Fix flaky comments tests
This commit is contained in:
Bryce Taylor 2021-12-02 16:31:53 -05:00 committed by GitHub
commit 17f726ef87
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 43 additions and 67 deletions

6
package-lock.json generated
View file

@ -4655,9 +4655,9 @@
} }
}, },
"chromedriver": { "chromedriver": {
"version": "95.0.0", "version": "96.0.0",
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-95.0.0.tgz", "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-96.0.0.tgz",
"integrity": "sha512-HwSg7S0ZZYsHTjULwxFHrrUqEpz1+ljDudJM3eOquvqD5QKnR5pSe/GlBTY9UU2tVFRYz8bEHYC4Y8qxciQiLQ==", "integrity": "sha512-4g6Hn5RHGsbaBmOrJbDlz/hdVPOc22eRsbvoAAMqkZxR2NJCcddHzCw2FAQeW8lX/C7xWVz3nyDsKX3fE9lIIw==",
"dev": true, "dev": true,
"requires": { "requires": {
"@testim/chrome-version": "^1.0.7", "@testim/chrome-version": "^1.0.7",

View file

@ -72,7 +72,7 @@
"babel-preset-es2015": "6.22.0", "babel-preset-es2015": "6.22.0",
"babel-preset-react": "6.22.0", "babel-preset-react": "6.22.0",
"bowser": "1.9.4", "bowser": "1.9.4",
"chromedriver": "95.0.0", "chromedriver": "96.0.0",
"classnames": "2.2.5", "classnames": "2.2.5",
"cookie": "0.4.1", "cookie": "0.4.1",
"copy-webpack-plugin": "4.6.0", "copy-webpack-plugin": "4.6.0",

View file

@ -3,11 +3,11 @@
import SeleniumHelper from './selenium-helpers.js'; import SeleniumHelper from './selenium-helpers.js';
const { const {
findByXpath,
buildDriver, buildDriver,
clickXpath,
clickText, clickText,
clickXpath,
containsClass, containsClass,
findByXpath,
signIn signIn
} = new SeleniumHelper(); } = new SeleniumHelper();
@ -61,7 +61,7 @@ describe('comment tests', async () => {
describe('leave comments', async () => { describe('leave comments', async () => {
beforeAll(async () => { beforeAll(async () => {
await signIn(username1, password, driver); await signIn(username1, password);
await findByXpath('//span[contains(@class, "profile-name")]'); await findByXpath('//span[contains(@class, "profile-name")]');
}); });
@ -80,10 +80,6 @@ describe('comment tests', async () => {
await findByXpath(`//textarea[contains(text(), "${projectComment}")]`); await findByXpath(`//textarea[contains(text(), "${projectComment}")]`);
await clickXpath('//button[@class="button compose-post"]'); await clickXpath('//button[@class="button compose-post"]');
// reload the page
await driver.sleep(5000);
await driver.get(projectUrl);
// find the comment // find the comment
let commentXpath = await `//div[@class="comment-bubble"]/span/span[contains(text(),` + let commentXpath = await `//div[@class="comment-bubble"]/span/span[contains(text(),` +
` "${projectComment}")]`; ` "${projectComment}")]`;
@ -101,9 +97,6 @@ describe('comment tests', async () => {
await commentArea.sendKeys(profileComment); await commentArea.sendKeys(profileComment);
await clickXpath('//div[@class="button small"]/a[contains(text(), "Post")]'); await clickXpath('//div[@class="button small"]/a[contains(text(), "Post")]');
// reload page
await driver.get(profileUrl);
// find the comment // find the comment
let newComment = await findByXpath(`//div[@class="comment "]/div/div[contains(text(),` + let newComment = await findByXpath(`//div[@class="comment "]/div/div[contains(text(),` +
` "${profileComment}")]`); ` "${profileComment}")]`);
@ -123,10 +116,6 @@ describe('comment tests', async () => {
await findByXpath(`//textarea[contains(text(), "${studioComment}")]`); await findByXpath(`//textarea[contains(text(), "${studioComment}")]`);
await clickXpath('//button[@class="button compose-post"]'); await clickXpath('//button[@class="button compose-post"]');
// reload the page
await driver.sleep(5000);
await driver.get(studioUrl);
// find the comment // find the comment
let commentXpath = `//div[@class="comment-bubble"]/span/span[contains(text(), "${studioComment}")]`; let commentXpath = `//div[@class="comment-bubble"]/span/span[contains(text(), "${studioComment}")]`;
let postedComment = await findByXpath(commentXpath); let postedComment = await findByXpath(commentXpath);
@ -137,7 +126,7 @@ describe('comment tests', async () => {
describe('second user tests', async () => { describe('second user tests', async () => {
beforeAll(async () => { beforeAll(async () => {
await signIn(username2, password, driver); await signIn(username2, password);
await findByXpath('//span[contains(@class, "profile-name")]'); await findByXpath('//span[contains(@class, "profile-name")]');
}); });
@ -277,9 +266,6 @@ describe('comment tests', async () => {
let postButton = await findByXpath(replyRow + '//button[@class = "button compose-post"]'); let postButton = await findByXpath(replyRow + '//button[@class = "button compose-post"]');
await postButton.click(); await postButton.click();
// find reply
await driver.sleep(500);
await driver.get(projectUrl);
let postedReply = await findByXpath(`//span[contains(text(), "${projectReply}")]`); let postedReply = await findByXpath(`//span[contains(text(), "${projectReply}")]`);
let commentVisible = await postedReply.isDisplayed(); let commentVisible = await postedReply.isDisplayed();
await expect(commentVisible).toBe(true); await expect(commentVisible).toBe(true);
@ -298,7 +284,6 @@ describe('comment tests', async () => {
// click post // click post
await clickXpath(commentXpath + '//a[contains(text(), "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 // The reply wasn't findable by xpath after several attempts, but it seems
// better to have this much of a test // better to have this much of a test
}); });
@ -321,8 +306,6 @@ describe('comment tests', async () => {
await postButton.click(); await postButton.click();
// find reply // find reply
await driver.sleep(500);
await driver.get(studioUrl);
let postedReply = await findByXpath(`//span[contains(text(), "${studioReply}")]`); let postedReply = await findByXpath(`//span[contains(text(), "${studioReply}")]`);
let commentVisible = await postedReply.isDisplayed(); let commentVisible = await postedReply.isDisplayed();
await expect(commentVisible).toBe(true); await expect(commentVisible).toBe(true);

View file

@ -3,10 +3,11 @@
const SeleniumHelper = require('./selenium-helpers.js'); const SeleniumHelper = require('./selenium-helpers.js');
const { const {
buildDriver,
clickText, clickText,
findByXpath,
clickXpath, clickXpath,
buildDriver findByXpath,
signIn
} = new SeleniumHelper(); } = new SeleniumHelper();
let username = process.env.SMOKE_USERNAME + '1'; let username = process.env.SMOKE_USERNAME + '1';
@ -30,14 +31,7 @@ describe('www-integration my_stuff', () => {
driver = await buildDriver('www-integration my_stuff'); driver = await buildDriver('www-integration my_stuff');
await driver.get(rootUrl); await driver.get(rootUrl);
await driver.sleep(1000); await driver.sleep(1000);
await clickXpath('//li[@class="link right login-item"]/a'); await signIn(username, password);
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 findByXpath('//span[contains(@class, "profile-name")]'); await findByXpath('//span[contains(@class, "profile-name")]');
}); });
@ -105,7 +99,7 @@ describe('www-integration my_stuff', () => {
await clickXpath('//form[@id="new_studio"]/button[@type="submit"]'); await clickXpath('//form[@id="new_studio"]/button[@type="submit"]');
let tabs = await findByXpath('//div[@class="studio-tabs"]'); let tabs = await findByXpath('//div[@class="studio-tabs"]');
let tabsVisible = await tabs.isDisplayed(); let tabsVisible = await tabs.isDisplayed();
expect(tabsVisible).toBe(true); await expect(tabsVisible).toBe(true);
}); });
test('New studio rate limited to five', async () =>{ test('New studio rate limited to five', async () =>{

View file

@ -3,9 +3,10 @@
const SeleniumHelper = require('./selenium-helpers.js'); const SeleniumHelper = require('./selenium-helpers.js');
const { const {
findByXpath, buildDriver,
clickXpath, clickXpath,
buildDriver findByXpath,
waitUntilVisible
} = new SeleniumHelper(); } = new SeleniumHelper();
let remote = process.env.SMOKE_REMOTE || false; let remote = process.env.SMOKE_REMOTE || false;
@ -31,7 +32,7 @@ describe('www-integration project-page signed out', () => {
beforeEach(async () => { beforeEach(async () => {
await driver.get(projectUrl); await driver.get(projectUrl);
let gfOverlay = await findByXpath('//div[@class="stage-wrapper_stage-wrapper_2bejr box_box_2jjDp"]'); 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()); afterAll(async () => await driver.quit());

View file

@ -151,15 +151,13 @@ class SeleniumHelper {
} }
// must be used on a www page // 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'); await this.clickXpath('//li[@class="link right login-item"]/a');
let name = await this.findByXpath('//input[@id="frc-username-1088"]'); let name = await this.findByXpath('//input[@id="frc-username-1088"]');
await name.sendKeys(username); await name.sendKeys(username);
let word = await this.findByXpath('//input[@id="frc-password-1088"]'); let word = await this.findByXpath('//input[@id="frc-password-1088"]');
await word.sendKeys(password); await word.sendKeys(password + this.getKey('ENTER'));
await driver.sleep(500); await this.findByXpath('//span[contains(@class, "profile-name")]');
await this.clickXpath('//button[contains(@class, "button") and ' +
'contains(@class, "submit-button") and contains(@class, "white")]');
} }
urlMatches (regex) { urlMatches (regex) {

View file

@ -3,11 +3,12 @@
const SeleniumHelper = require('./selenium-helpers.js'); const SeleniumHelper = require('./selenium-helpers.js');
const { const {
clickText,
findByXpath,
clickXpath,
clickButton,
buildDriver, buildDriver,
clickButton,
clickText,
clickXpath,
findByXpath,
getKey,
signIn, signIn,
waitUntilVisible waitUntilVisible
} = new SeleniumHelper(); } = new SeleniumHelper();
@ -77,7 +78,7 @@ describe('www-integration sign-in-and-out', () => {
describe('sign out', () => { describe('sign out', () => {
beforeEach(async () => { beforeEach(async () => {
await driver.get(wwwURL); await driver.get(wwwURL);
await signIn(username, password, driver); await signIn(username, password);
await driver.sleep(500); await driver.sleep(500);
}); });
@ -108,11 +109,11 @@ describe('www-integration sign-in-and-out', () => {
await driver.get(scratchr2url); await driver.get(scratchr2url);
await clickXpath('//li[@class="sign-in dropdown"]/span'); await clickXpath('//li[@class="sign-in dropdown"]/span');
let name = await findByXpath('//input[@id="login_dropdown_username"]'); let name = await findByXpath('//input[@id="login_dropdown_username"]');
await name.sendKeys(nonsenseUsername); await name.sendKeys(nonsenseUsername + getKey('ENTER'));
await clickButton('Sign in');
// find error // find error
let error = await findByXpath('//form[@id="login"]//div[@class="error"]'); let error = await findByXpath('//form[@id="login"]//div[@class="error"]');
await waitUntilVisible(error, driver);
let errorText = await error.getText(); let errorText = await error.getText();
await expect(errorText).toEqual('This field is required.'); await expect(errorText).toEqual('This field is required.');
}); });
@ -126,8 +127,7 @@ describe('www-integration sign-in-and-out', () => {
let name = await findByXpath('//input[@id="login_dropdown_username"]'); let name = await findByXpath('//input[@id="login_dropdown_username"]');
await name.sendKeys(nonsenseUsername); await name.sendKeys(nonsenseUsername);
let word = await findByXpath('//input[@name="password"]'); let word = await findByXpath('//input[@name="password"]');
await word.sendKeys(password); await word.sendKeys(password + getKey('ENTER'));
await clickButton('Sign in');
// find error // find error
let error = await findByXpath('//form[@id="login"]//div[@class="error"]'); let error = await findByXpath('//form[@id="login"]//div[@class="error"]');
@ -145,8 +145,7 @@ describe('www-integration sign-in-and-out', () => {
let name = await findByXpath('//input[@id="login_dropdown_username"]'); let name = await findByXpath('//input[@id="login_dropdown_username"]');
await name.sendKeys(username); await name.sendKeys(username);
let word = await findByXpath('//input[@name="password"]'); let word = await findByXpath('//input[@name="password"]');
await word.sendKeys(nonsensePassword); await word.sendKeys(nonsensePassword + getKey('ENTER'));
await clickButton('Sign in');
// find error // find error
let error = await findByXpath('//form[@id="login"]//div[@class="error"]'); let error = await findByXpath('//form[@id="login"]//div[@class="error"]');

View file

@ -78,14 +78,14 @@ describe('studio management', () => {
await driver.get(rootUrl); await driver.get(rootUrl);
// create a studio for tests // create a studio for tests
await signIn(username2, password, driver); await signIn(username2, password);
await findByXpath('//span[contains(@class, "profile-name")]'); await findByXpath('//span[contains(@class, "profile-name")]');
await driver.get(rateLimitCheck); await driver.get(rateLimitCheck);
await driver.get(myStuffURL); await driver.get(myStuffURL);
await clickXpath('//form[@id="new_studio"]/button[@type="submit"]'); await clickXpath('//form[@id="new_studio"]/button[@type="submit"]');
await findByXpath('//div[@class="studio-tabs"]'); await findByXpath('//div[@class="studio-tabs"]');
promoteStudioURL = await driver.getCurrentUrl(); promoteStudioURL = await driver.getCurrentUrl();
curatorTab = promoteStudioURL + 'curators'; curatorTab = await promoteStudioURL + 'curators';
}); });
beforeEach(async () => { beforeEach(async () => {
@ -99,7 +99,7 @@ describe('studio management', () => {
test('invite a curator', async () => { test('invite a curator', async () => {
// sign in as user2 // sign in as user2
await signIn(username2, password, driver); await signIn(username2, password);
await findByXpath('//span[contains(@class, "profile-name")]'); await findByXpath('//span[contains(@class, "profile-name")]');
// invite user3 to curate // invite user3 to curate
@ -108,13 +108,13 @@ describe('studio management', () => {
await clickXpath('//div[@class="studio-adder-row"]/button'); await clickXpath('//div[@class="studio-adder-row"]/button');
let inviteAlert = await findByXpath('//div[@class="alert-msg"]'); // the confirm alert let inviteAlert = await findByXpath('//div[@class="alert-msg"]'); // the confirm alert
let alertText = await inviteAlert.getText(); 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); await expect(alertText).toMatch(successText);
}); });
test('accept curator invite', async () => { test('accept curator invite', async () => {
// Sign in user3 // Sign in user3
await signIn(username3, password, driver); await signIn(username3, password);
await findByXpath('//span[contains(@class, "profile-name")]'); await findByXpath('//span[contains(@class, "profile-name")]');
// accept the curator invite // accept the curator invite
@ -126,15 +126,16 @@ describe('studio management', () => {
test('promote to manager', async () => { test('promote to manager', async () => {
// sign in as user2 // sign in as user2
await signIn(username2, password, driver); await signIn(username2, password);
await findByXpath('//span[contains(@class, "profile-name")]'); 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); await driver.get(curatorTab);
// promote user3 // promote user3
let user3href = '/users/' + username3; let user3href = await '/users/' + username3;
// click kebab menu on the user tile // 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"]'; 'following-sibling::div[@class="overflow-menu-container"]';
await clickXpath(kebabMenuXpath + '/button[@class="overflow-menu-trigger"]'); await clickXpath(kebabMenuXpath + '/button[@class="overflow-menu-trigger"]');
// click promote // click promote
@ -150,15 +151,15 @@ describe('studio management', () => {
test('transfer studio host', async () => { test('transfer studio host', async () => {
// sign in as user2 // sign in as user2
await signIn(username2, password, driver); await signIn(username2, password);
await findByXpath('//span[contains(@class, "profile-name")]'); 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 reloading the page
await driver.get(curatorTab); await driver.get(curatorTab);
// open kebab menu // open kebab menu
let user2href = '/users/' + username2; let user2href = await '/users/' + username2;
// click kebab menu on the user tile // 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"]'; 'following-sibling::div[@class="overflow-menu-container"]';
await clickXpath(kebabMenuXpath + '/button[@class="overflow-menu-trigger"]'); await clickXpath(kebabMenuXpath + '/button[@class="overflow-menu-trigger"]');