mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-11-27 17:45:52 -05:00
Merge pull request #5946 from BryceLTaylor/studio-management-integration-tests
Studio management integration tests
This commit is contained in:
commit
d23e4d6ceb
11 changed files with 164 additions and 46 deletions
69
package-lock.json
generated
69
package-lock.json
generated
|
@ -1986,9 +1986,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"@nodelib/fs.walk": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz",
|
||||
"integrity": "sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA==",
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
|
||||
"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@nodelib/fs.scandir": "2.1.5",
|
||||
|
@ -2153,9 +2153,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"@types/yauzl": {
|
||||
"version": "2.9.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz",
|
||||
"integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==",
|
||||
"version": "2.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz",
|
||||
"integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
@ -2456,9 +2456,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
|
||||
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
|
@ -4990,9 +4990,9 @@
|
|||
}
|
||||
},
|
||||
"chromedriver": {
|
||||
"version": "91.0.1",
|
||||
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-91.0.1.tgz",
|
||||
"integrity": "sha512-9LktpHiUxM4UWUsr+jI1K1YKx2GENt6BKKJ2mibPj1Wc6ODzX/3fFIlr8CZ4Ftuyga+dHTTbAyPWKwKvybEbKA==",
|
||||
"version": "92.0.1",
|
||||
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-92.0.1.tgz",
|
||||
"integrity": "sha512-LptlDVCs1GgyFNVbRoHzzy948JDVzTgGiVPXjNj385qXKQP3hjAVBIgyvb/Hco0xSEW8fjwJfsm1eQRmu6t4pQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@testim/chrome-version": "^1.0.7",
|
||||
|
@ -6626,9 +6626,9 @@
|
|||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.2.6",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
|
||||
"integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
|
||||
"version": "4.2.8",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
|
||||
"integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
|
||||
"dev": true
|
||||
},
|
||||
"ignore": {
|
||||
|
@ -8025,9 +8025,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
|
||||
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
|
@ -8064,17 +8064,16 @@
|
|||
"integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ="
|
||||
},
|
||||
"fast-glob": {
|
||||
"version": "3.2.5",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz",
|
||||
"integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==",
|
||||
"version": "3.2.7",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz",
|
||||
"integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@nodelib/fs.stat": "^2.0.2",
|
||||
"@nodelib/fs.walk": "^1.2.3",
|
||||
"glob-parent": "^5.1.0",
|
||||
"glob-parent": "^5.1.2",
|
||||
"merge2": "^1.3.0",
|
||||
"micromatch": "^4.0.2",
|
||||
"picomatch": "^2.2.1"
|
||||
"micromatch": "^4.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"braces": {
|
||||
|
@ -8133,15 +8132,13 @@
|
|||
"requires": {
|
||||
"braces": "^3.0.1",
|
||||
"picomatch": "^2.2.3"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"picomatch": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
|
||||
"integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
|
@ -8258,9 +8255,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"fastq": {
|
||||
"version": "1.11.0",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz",
|
||||
"integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==",
|
||||
"version": "1.12.0",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.12.0.tgz",
|
||||
"integrity": "sha512-VNX0QkHK3RsXVKr9KrlUv/FoTa0NdbYoHHl7uXHv2rzyHSlxjdNAKug2twd9luJxpcyNeAgf5iPPMutJO67Dfg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"reusify": "^1.0.4"
|
||||
|
@ -8868,9 +8865,9 @@
|
|||
}
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz",
|
||||
"integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==",
|
||||
"version": "1.14.2",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.2.tgz",
|
||||
"integrity": "sha512-yLR6WaE2lbF0x4K2qE2p9PEXKLDjUjnR/xmjS3wHAYxtlsI9MLLBJUZirAHKzUZDGLxje7w/cXR49WOUo4rbsA==",
|
||||
"dev": true
|
||||
},
|
||||
"font-atlas": {
|
||||
|
@ -11077,9 +11074,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
|
||||
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
|
|
|
@ -76,7 +76,7 @@
|
|||
"babel-preset-es2015": "6.22.0",
|
||||
"babel-preset-react": "6.22.0",
|
||||
"bowser": "1.9.4",
|
||||
"chromedriver": "91.0.1",
|
||||
"chromedriver": "92.0.1",
|
||||
"classnames": "2.2.5",
|
||||
"cookie": "0.4.1",
|
||||
"copy-webpack-plugin": "4.6.0",
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// these tests do not sign in as a user
|
||||
|
||||
const SeleniumHelper = require('./selenium-helpers.js');
|
||||
|
||||
const {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// these tests do not sign in as a user
|
||||
|
||||
const SeleniumHelper = require('./selenium-helpers.js');
|
||||
|
||||
const {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// these tests do not sign in as a user
|
||||
|
||||
const SeleniumHelper = require('./selenium-helpers.js');
|
||||
|
||||
const {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// These tests sign in as user #1
|
||||
|
||||
const SeleniumHelper = require('./selenium-helpers.js');
|
||||
|
||||
const {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// These tests do not sign in as a user
|
||||
|
||||
const SeleniumHelper = require('./selenium-helpers.js');
|
||||
|
||||
const {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// These tests do not sign in with a user
|
||||
|
||||
const SeleniumHelper = require('./selenium-helpers.js');
|
||||
|
||||
const {
|
||||
|
|
|
@ -29,6 +29,7 @@ class SeleniumHelper {
|
|||
'getDriver',
|
||||
'getLogs',
|
||||
'getSauceDriver',
|
||||
'signIn',
|
||||
'urlMatches',
|
||||
'waitUntilGone'
|
||||
]);
|
||||
|
@ -148,6 +149,18 @@ class SeleniumHelper {
|
|||
});
|
||||
}
|
||||
|
||||
// must be used on a www page
|
||||
async signIn (username, password, driver) {
|
||||
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")]');
|
||||
}
|
||||
|
||||
urlMatches (regex) {
|
||||
return this.driver.wait(until.urlMatches(regex), 1000 * 5);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// These tests sign in with user #0 (no number for the username)
|
||||
|
||||
const SeleniumHelper = require('./selenium-helpers.js');
|
||||
|
||||
const {
|
||||
|
|
|
@ -1,17 +1,33 @@
|
|||
// These tests sign in with user #2 and user #3
|
||||
|
||||
import SeleniumHelper from './selenium-helpers.js';
|
||||
|
||||
const {
|
||||
findByXpath,
|
||||
buildDriver
|
||||
buildDriver,
|
||||
clickXpath,
|
||||
clickText,
|
||||
signIn
|
||||
} = new SeleniumHelper();
|
||||
|
||||
let remote = process.env.SMOKE_REMOTE || false;
|
||||
let rootUrl = process.env.ROOT_URL || 'https://scratch.ly';
|
||||
let studioId = process.env.TEST_STUDIO_ID || 10004360;
|
||||
let studioUrl = rootUrl + '/studios/' + studioId;
|
||||
let myStuffURL = rootUrl + '/mystuff';
|
||||
let rateLimitCheck = process.env.RATE_LIMIT_CHECK || rootUrl;
|
||||
|
||||
// since the usernames end in 2 and 3 we're using username2 and username3
|
||||
// username 1 is used in other tests. Hopefully this is not confusing.
|
||||
let username2 = process.env.SMOKE_USERNAME + '2';
|
||||
let username3 = process.env.SMOKE_USERNAME + '3';
|
||||
let password = process.env.SMOKE_PASSWORD;
|
||||
|
||||
let promoteStudioURL;
|
||||
let curatorTab;
|
||||
|
||||
if (remote){
|
||||
jest.setTimeout(60000);
|
||||
jest.setTimeout(70000);
|
||||
} else {
|
||||
jest.setTimeout(20000);
|
||||
}
|
||||
|
@ -52,5 +68,83 @@ describe('studio page while signed out', () => {
|
|||
let descriptionText = await studioDescription.getText();
|
||||
await expect(descriptionText).toEqual('a description');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('studio management', () => {
|
||||
// These tests all start on the curators tab of a studio and signed out
|
||||
|
||||
beforeAll(async () => {
|
||||
driver = await buildDriver('www-integration studio management');
|
||||
await driver.get(rootUrl);
|
||||
|
||||
// create a studio for tests
|
||||
await signIn(username2, password, driver);
|
||||
await findByXpath('//span[contains(@class, "profile-name")]');
|
||||
await driver.get(rateLimitCheck);
|
||||
await driver.get(myStuffURL);
|
||||
await clickXpath('//form[@id="new_studio"]/button[@type="submit"]');
|
||||
await findByXpath('//div[@class="studio-tabs"]');
|
||||
promoteStudioURL = await driver.getCurrentUrl();
|
||||
curatorTab = promoteStudioURL + 'curators';
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await clickXpath('//a[contains(@class, "user-info")]');
|
||||
await clickText('Sign out');
|
||||
await driver.get(curatorTab);
|
||||
await findByXpath('//div[@class="studio-tabs"]');
|
||||
});
|
||||
|
||||
afterAll(async () => await driver.quit());
|
||||
|
||||
test('invite a curator', async () => {
|
||||
// sign in as user2
|
||||
await signIn(username2, password, driver);
|
||||
await findByXpath('//span[contains(@class, "profile-name")]');
|
||||
|
||||
// invite user3 to curate
|
||||
let inviteBox = await findByXpath('//div[@class="studio-adder-row"]/input');
|
||||
await inviteBox.sendKeys(username3);
|
||||
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}"`;
|
||||
await expect(alertText).toMatch(successText);
|
||||
});
|
||||
|
||||
test('accept curator invite', async () => {
|
||||
// Sign in user3
|
||||
await signIn(username3, password, driver);
|
||||
await findByXpath('//span[contains(@class, "profile-name")]');
|
||||
|
||||
// accept the curator invite
|
||||
await clickXpath('//button[@class="studio-invitation-button button"]');
|
||||
let acceptSuccess = await findByXpath('//div[contains(@class,"studio-info-box-success")]');
|
||||
let acceptSuccessVisible = await acceptSuccess.isDisplayed();
|
||||
await expect(acceptSuccessVisible).toBe(true);
|
||||
});
|
||||
|
||||
test('promote to manager', async () => {
|
||||
// sign in as user2
|
||||
await signIn(username2, password, driver);
|
||||
await findByXpath('//span[contains(@class, "profile-name")]');
|
||||
// for some reason the user isn't showing up without reloading the page
|
||||
await driver.get(curatorTab);
|
||||
|
||||
// promote user3
|
||||
let user3href = '/users/' + username3;
|
||||
// click kebab menu on the user tile
|
||||
let kebabMenuXpath = `//a[@href = "${user3href}"]/` +
|
||||
'following-sibling::div[@class="overflow-menu-container"]';
|
||||
await clickXpath(kebabMenuXpath + '/button[@class="overflow-menu-trigger"]');
|
||||
// click promote
|
||||
// await clickXpath('//button[@class="promote-menu-button"]'); //<-- I think this will do it
|
||||
await clickXpath(kebabMenuXpath + '/ul/li/button/span[contains(text(), "Promote")]/..');
|
||||
await findByXpath('//div[@class="promote-content"]');
|
||||
// await clickXpath(//button[contains(@class="promote-button")]) <-- add this selector to the button
|
||||
await clickXpath('//div[@class="promote-button-row"]/button/span[contains(text(),"Promote")]/..');
|
||||
let promoteSuccess = await findByXpath('//div[contains(@class, "alert-success")]');
|
||||
let promoteSuccessVisible = await promoteSuccess.isDisplayed();
|
||||
await expect(promoteSuccessVisible).toBe(true);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue