mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-11-23 15:47:53 -05:00
Merge pull request #6351 from BryceLTaylor/fix-flaky-comments-tests
Fix flaky comments tests
This commit is contained in:
commit
17f726ef87
8 changed files with 43 additions and 67 deletions
6
package-lock.json
generated
6
package-lock.json
generated
|
@ -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",
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 () =>{
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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"]');
|
||||||
|
|
|
@ -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"]');
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue