diff --git a/services/static-webserver/client/source/class/osparc/dashboard/GridButtonBase.js b/services/static-webserver/client/source/class/osparc/dashboard/GridButtonBase.js index 5b9e19f184ff..34796bcec189 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/GridButtonBase.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/GridButtonBase.js @@ -140,6 +140,7 @@ qx.Class.define("osparc.dashboard.GridButtonBase", { const hGrid = new qx.ui.layout.Grid().set({ spacing: 6, }); + hGrid.setRowFlex(0, 1); hGrid.setColumnFlex(1, 1); hGrid.setColumnAlign(0, "right", "middle"); hGrid.setColumnAlign(1, "left", "middle"); @@ -149,6 +150,7 @@ qx.Class.define("osparc.dashboard.GridButtonBase", { paddingBottom: 6, paddingRight: 4, maxWidth: this.self().ITEM_WIDTH, + minHeight: 32 + 6, maxHeight: this.self().ITEM_HEIGHT }); control.setLayout(hGrid); @@ -283,18 +285,11 @@ qx.Class.define("osparc.dashboard.GridButtonBase", { // overridden _applyThumbnail: function(value, old) { - if (value.includes("@FontAwesome5Solid/")) { + if (qx.util.ResourceManager.getInstance().isFontUri(value)) { value += this.self().THUMBNAIL_SIZE; - const image = this.getChildControl("thumbnail").set({ + this.getChildControl("thumbnail").set({ source: value, }); - - [ - "appear", - "loaded" - ].forEach(eventName => { - image.addListener(eventName, () => this.__fitThumbnailHeight(), this); - }); } else { let source = osparc.product.Utils.getThumbnailUrl(); osparc.utils.Utils.checkImageExists(value) diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ServiceBrowser.js b/services/static-webserver/client/source/class/osparc/dashboard/ServiceBrowser.js index 1733f4d5ae9f..0d6ece141027 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ServiceBrowser.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ServiceBrowser.js @@ -48,7 +48,7 @@ qx.Class.define("osparc.dashboard.ServiceBrowser", { // overridden initResources: function() { this._resourcesList = []; - osparc.store.Services.getServicesLatest(false) + osparc.store.Services.getServicesLatest() .then(services => { // Show "Contact Us" message if services.length === 0 // Most probably is a product-stranger user (it can also be that the catalog is down) diff --git a/services/static-webserver/client/source/class/osparc/study/Utils.js b/services/static-webserver/client/source/class/osparc/study/Utils.js index c0263fee78e5..096861a3068d 100644 --- a/services/static-webserver/client/source/class/osparc/study/Utils.js +++ b/services/static-webserver/client/source/class/osparc/study/Utils.js @@ -169,80 +169,83 @@ qx.Class.define("osparc.study.Utils", { createStudyFromTemplate: function(templateData, loadingPage, contextProps = {}) { return new Promise((resolve, reject) => { - const inaccessibleServices = osparc.store.Services.getInaccessibleServices(templateData["workbench"]); - if (inaccessibleServices.length) { - const msg = osparc.store.Services.getInaccessibleServicesMsg(inaccessibleServices, templateData["workbench"]); - reject({ - message: msg + osparc.store.Services.getStudyServicesMetadata(templateData) + .finally(() => { + const inaccessibleServices = osparc.store.Services.getInaccessibleServices(templateData["workbench"]); + if (inaccessibleServices.length) { + const msg = osparc.store.Services.getInaccessibleServicesMsg(inaccessibleServices, templateData["workbench"]); + reject({ + message: msg + }); + return; + } + // context props, otherwise Study will be created in the root folder of my personal workspace + const minStudyData = Object.assign(osparc.data.model.Study.createMinStudyObject(), contextProps); + minStudyData["name"] = templateData["name"]; + minStudyData["description"] = templateData["description"]; + minStudyData["thumbnail"] = templateData["thumbnail"]; + const params = { + url: { + templateId: templateData["uuid"] + }, + data: minStudyData + }; + const options = { + pollTask: true + }; + const fetchPromise = osparc.data.Resources.fetch("studies", "postNewStudyFromTemplate", params, options); + const pollTasks = osparc.data.PollTasks.getInstance(); + const interval = 1000; + pollTasks.createPollingTask(fetchPromise, interval) + .then(task => { + const title = qx.locale.Manager.tr("CREATING ") + osparc.product.Utils.getStudyAlias({allUpperCase: true}) + " ..."; + const progressSequence = new osparc.widget.ProgressSequence(title).set({ + minHeight: 180 // four tasks + }); + progressSequence.addOverallProgressBar(); + loadingPage.clearMessages(); + loadingPage.addWidgetToMessages(progressSequence); + task.addListener("updateReceived", e => { + const updateData = e.getData(); + if ("task_progress" in updateData && loadingPage) { + const progress = updateData["task_progress"]; + const message = progress["message"]; + const percent = progress["percent"] ? parseFloat(progress["percent"].toFixed(3)) : progress["percent"]; + progressSequence.setOverallProgress(percent); + const existingTask = progressSequence.getTask(message); + if (existingTask) { + // update task + osparc.widget.ProgressSequence.updateTaskProgress(existingTask, { + value: percent, + progressLabel: parseFloat((percent*100).toFixed(2)) + "%" + }); + } else { + // new task + // all the previous steps to 100% + progressSequence.getTasks().forEach(tsk => osparc.widget.ProgressSequence.updateTaskProgress(tsk, { + value: 1, + progressLabel: "100%" + })); + // and move to the next new task + const subTask = progressSequence.addNewTask(message); + osparc.widget.ProgressSequence.updateTaskProgress(subTask, { + value: percent, + progressLabel: "0%" + }); + } + } + }, this); + task.addListener("resultReceived", e => { + const studyData = e.getData(); + resolve(studyData); + }, this); + task.addListener("pollingError", e => { + const err = e.getData(); + reject(err); + }, this); + }) + .catch(err => reject(err)); }); - return; - } - // context props, otherwise Study will be created in the root folder of my personal workspace - const minStudyData = Object.assign(osparc.data.model.Study.createMinStudyObject(), contextProps); - minStudyData["name"] = templateData["name"]; - minStudyData["description"] = templateData["description"]; - minStudyData["thumbnail"] = templateData["thumbnail"]; - const params = { - url: { - templateId: templateData["uuid"] - }, - data: minStudyData - }; - const options = { - pollTask: true - }; - const fetchPromise = osparc.data.Resources.fetch("studies", "postNewStudyFromTemplate", params, options); - const pollTasks = osparc.data.PollTasks.getInstance(); - const interval = 1000; - pollTasks.createPollingTask(fetchPromise, interval) - .then(task => { - const title = qx.locale.Manager.tr("CREATING ") + osparc.product.Utils.getStudyAlias({allUpperCase: true}) + " ..."; - const progressSequence = new osparc.widget.ProgressSequence(title).set({ - minHeight: 180 // four tasks - }); - progressSequence.addOverallProgressBar(); - loadingPage.clearMessages(); - loadingPage.addWidgetToMessages(progressSequence); - task.addListener("updateReceived", e => { - const updateData = e.getData(); - if ("task_progress" in updateData && loadingPage) { - const progress = updateData["task_progress"]; - const message = progress["message"]; - const percent = progress["percent"] ? parseFloat(progress["percent"].toFixed(3)) : progress["percent"]; - progressSequence.setOverallProgress(percent); - const existingTask = progressSequence.getTask(message); - if (existingTask) { - // update task - osparc.widget.ProgressSequence.updateTaskProgress(existingTask, { - value: percent, - progressLabel: parseFloat((percent*100).toFixed(2)) + "%" - }); - } else { - // new task - // all the previous steps to 100% - progressSequence.getTasks().forEach(tsk => osparc.widget.ProgressSequence.updateTaskProgress(tsk, { - value: 1, - progressLabel: "100%" - })); - // and move to the next new task - const subTask = progressSequence.addNewTask(message); - osparc.widget.ProgressSequence.updateTaskProgress(subTask, { - value: percent, - progressLabel: "0%" - }); - } - } - }, this); - task.addListener("resultReceived", e => { - const studyData = e.getData(); - resolve(studyData); - }, this); - task.addListener("pollingError", e => { - const err = e.getData(); - reject(err); - }, this); - }) - .catch(err => reject(err)); }); }, diff --git a/services/static-webserver/client/source/class/osparc/workbench/ServiceCatalog.js b/services/static-webserver/client/source/class/osparc/workbench/ServiceCatalog.js index 94229ae175e0..1679b23bcd69 100644 --- a/services/static-webserver/client/source/class/osparc/workbench/ServiceCatalog.js +++ b/services/static-webserver/client/source/class/osparc/workbench/ServiceCatalog.js @@ -247,7 +247,10 @@ qx.Class.define("osparc.workbench.ServiceCatalog", { osparc.store.Services.populateVersionsSelectBox(key, selectBox) .then(() => { osparc.utils.Utils.growSelectBox(selectBox, 200); - selectBox.setSelection([latest]); + const idx = selectBox.getSelectables().indexOf(latest); + if (idx > -1) { + selectBox.setSelection([latest]); + } }); } } diff --git a/tests/e2e/jest.config.js b/tests/e2e/jest.config.js index c0a66be33618..8c91e5eea9f9 100644 --- a/tests/e2e/jest.config.js +++ b/tests/e2e/jest.config.js @@ -1,7 +1,7 @@ module.exports = { preset: "jest-puppeteer", verbose: true, - collectCoverage: true, + collectCoverage: false, coverageReporters: ["lcov", "text"], globals: { url: "http://127.0.0.1.nip.io:9081/", // For local testing, set your deployed url here diff --git a/tests/e2e/tests/register.js b/tests/e2e/tests/register.js new file mode 100644 index 000000000000..560a1e535fef --- /dev/null +++ b/tests/e2e/tests/register.js @@ -0,0 +1,75 @@ +const auto = require('../utils/auto'); +const utils = require('../utils/utils'); + + +const { + user, + pass +} = utils.getUserAndPass(); + +module.exports = { + registerAndLogOut: () => { + describe('Register and LogOut', () => { + const firstHandler = async response => { + if (response.url().endsWith("/config")) { + try { + const respStatus = response.status(); + expect(respStatus).toBe(200); + const responseBody = await response.json(); + expect(responseBody.data["invitation_required"]).toBeFalsy(); + } catch (e) { + console.log("Puppeteer error", e); + } + } else if (response.url().endsWith("/register")) { + try { + const respStatus = response.status(); + expect(respStatus).toBe(200); + } catch (e) { + console.log("Puppeteer error", e); + } + } + } + + const secondHandler = response => { + if (response.url().endsWith("/login")) { + try { + const respStatus = response.status(); + expect(respStatus).toBe(200); + } catch (e) { + console.log("Puppeteer error", e); + } + } else if (response.url().endsWith("/me")) { + try { + const respStatus = response.status(); + expect(respStatus).toBe(200); + } catch (e) { + console.log("Puppeteer error", e); + } + } else if (response.url().endsWith("/logout")) { + expect(response.status()).toBe(200); + } + } + + beforeAll(async () => { + console.log("Start:", new Date().toUTCString()); + + await page.goto(url); + }, ourTimeout); + + afterAll(async () => { + page.off('response', firstHandler); + page.off('response', secondHandler); + + console.log("End:", new Date().toUTCString()); + }) + + test('Register and Log Out', async () => { + page.on('response', firstHandler); + await auto.register(page, user, pass); + page.on('response', secondHandler); + await auto.logOut(page); + await page.waitFor(5000); + }, ourTimeout); + }); + } +} diff --git a/tests/e2e/tests/register.test.js b/tests/e2e/tests/register.test.js deleted file mode 100644 index 65bf701bd824..000000000000 --- a/tests/e2e/tests/register.test.js +++ /dev/null @@ -1,71 +0,0 @@ -const auto = require('../utils/auto'); -const utils = require('../utils/utils'); - -const { - user, - pass -} = utils.getUserAndPass(); - -const firstHandler = async response => { - if (response.url().endsWith("/config")) { - try { - const respStatus = response.status(); - expect(respStatus).toBe(200); - const responseBody = await response.json(); - expect(responseBody.data["invitation_required"]).toBeFalsy(); - } - catch (e) { - console.log("Pptr error", e); - } - } - else if (response.url().endsWith("/register")) { - try { - const respStatus = response.status(); - expect(respStatus).toBe(200); - } - catch (e) { - console.log("Pptr error", e); - } - } -} - -const secondHandler = response => { - if (response.url().endsWith("/login")) { - try { - const respStatus = response.status(); - expect(respStatus).toBe(200); - } - catch (e) { - console.log("Pptr error", e); - } - } - else if (response.url().endsWith("/me")) { - try { - const respStatus = response.status(); - expect(respStatus).toBe(200); - } - catch (e) { - console.log("Pptr error", e); - } - } - else if (response.url().endsWith("/logout")) { - expect(response.status()).toBe(200); - } -} - -beforeAll(async () => { - await page.goto(url); -}, ourTimeout); - -afterAll(async () => { - page.off('response', firstHandler); - page.off('response', secondHandler); -}) - -test('Register and Log Out', async () => { - page.on('response', firstHandler); - await auto.register(page, user, pass); - page.on('response', secondHandler); - await auto.logOut(page); - await page.waitFor(5000); -}, ourTimeout); diff --git a/tests/e2e/tests/startupCalls.js b/tests/e2e/tests/startupCalls.js new file mode 100644 index 000000000000..cadffad1ef74 --- /dev/null +++ b/tests/e2e/tests/startupCalls.js @@ -0,0 +1,73 @@ +const auto = require('../utils/auto'); +const utils = require('../utils/utils'); + +module.exports = { + startupCalls: () => { + describe('Calls after logging in', () => { + const { + user, + pass + } = utils.getUserAndPass(); + + const responses = { + me: null, + studies: null, + templates: null, + services: null, + }; + + beforeAll(async () => { + console.log("Start:", new Date().toUTCString()); + + page.on('response', response => { + const url = response.url(); + if (url.endsWith('/me')) { + responses.me = response.json(); + } else if (url.includes('projects?type=user')) { + responses.studies = response.json(); + } else if (url.includes('projects?type=template')) { + responses.templates = response.json(); + } else if (url.includes('catalog/services/-/latest')) { + responses.services = response.json(); + } + }); + + await page.goto(url); + + console.log("Registering user"); + await auto.register(page, user, pass); + console.log("Registered"); + + await page.waitFor(10000); + }, ourTimeout); + + afterAll(async () => { + await auto.logOut(page); + + console.log("End:", new Date().toUTCString()); + }, ourTimeout); + + test('Profile', async () => { + const responseEnv = await responses.me; + expect(responseEnv.data["login"]).toBe(user); + }, ourTimeout); + + test('Studies', async () => { + const responseEnv = await responses.studies; + expect(Array.isArray(responseEnv.data)).toBeTruthy(); + }, ourTimeout); + + test('Templates', async () => { + const responseEnv = await responses.templates; + expect(Array.isArray(responseEnv.data)).toBeTruthy(); + }, ourTimeout); + + test('Services', async () => { + const responseEnv = await responses.services; + expect(responseEnv.data._meta.total).toBeGreaterThan(0); + expect(Array.isArray(responseEnv.data.data)).toBeTruthy(); + expect(responseEnv.data.data.length).toBeGreaterThan(0); + }, ourTimeout); + }); + } +} diff --git a/tests/e2e/tests/startupCalls.test.js b/tests/e2e/tests/startupCalls.test.js deleted file mode 100644 index 1a1256963f5c..000000000000 --- a/tests/e2e/tests/startupCalls.test.js +++ /dev/null @@ -1,65 +0,0 @@ -const auto = require('../utils/auto'); -const utils = require('../utils/utils'); - -describe('Calls after logging in', () => { - const { - user, - pass - } = utils.getUserAndPass(); - - const responses = { - me: null, - studies: null, - templates: null, - services: null, - }; - - beforeAll(async () => { - page.on('response', response => { - const url = response.url(); - if (url.endsWith('/me')) { - responses.me = response.json(); - } else if (url.includes('projects?type=user')) { - responses.studies = response.json(); - } else if (url.includes('projects?type=template')) { - responses.templates = response.json(); - } else if (url.includes('catalog/services/-/latest')) { - responses.services = response.json(); - } - }); - - await page.goto(url); - - console.log("Registering user"); - await auto.register(page, user, pass); - console.log("Registered"); - - await page.waitFor(10000); - }, ourTimeout); - - afterAll(async () => { - await auto.logOut(page); - }, ourTimeout); - - test('Profile', async () => { - const responseEnv = await responses.me; - expect(responseEnv.data["login"]).toBe(user); - }, ourTimeout); - - test('Studies', async () => { - const responseEnv = await responses.studies; - expect(Array.isArray(responseEnv.data)).toBeTruthy(); - }, ourTimeout); - - test('Templates', async () => { - const responseEnv = await responses.templates; - expect(Array.isArray(responseEnv.data)).toBeTruthy(); - }, ourTimeout); - - test('Services', async () => { - const responseEnv = await responses.services; - expect(responseEnv.data._meta.total).toBeGreaterThan(0); - expect(Array.isArray(responseEnv.data.data)).toBeTruthy(); - expect(responseEnv.data.data.length).toBeGreaterThan(0); - }, ourTimeout); -}); diff --git a/tests/e2e/tests/tags.js b/tests/e2e/tests/tags.js new file mode 100644 index 000000000000..0814f11d47da --- /dev/null +++ b/tests/e2e/tests/tags.js @@ -0,0 +1,159 @@ +const utils = require('../utils/utils'); +const auto = require('../utils/auto'); +const waitAndClick = require('../utils/utils').waitAndClick; + + +module.exports = { + testTags: () => { + describe('tags testing', () => { + const { + user, + pass, + } = utils.getUserAndPass(); + + const TAG_NAME = 'tag_test'; + const TAG_NAME_2 = 'tag_test_2'; + let studyId = null; + let tagId = null; + + /** + * This function records the IDs of the study and tag created in order to later remove them. + */ + const responseHandler = response => { + if (response.url().endsWith('/tags') && response.request().method() === 'POST') { + response.json() + .then(({ + data: { + id + } + }) => { + console.log("Tag created, id", id); + tagId = id; + }); + } + if (response.url().endsWith('/projects') && response.request().method() === 'POST') { + response.json() + .then(({ + data: { + uuid + } + }) => { + console.log("Study created, uuid", uuid); + studyId = uuid; + }); + } + } + + beforeAll(async () => { + page.on('response', responseHandler); + await page.goto(url); + await auto.register(page, user, pass); + // Create new study + const uiConfig = await page.evaluate(async () => await osparc.store.Products.getInstance().fetchUiConfig()); + if ("plusButton" in uiConfig) { + await waitAndClick(page, '[osparc-test-id="newPlusBtn"]'); + } + await waitAndClick(page, '[osparc-test-id="emptyStudyBtn"]'); + // Wait until project is created and Dashboard button is enabled + await utils.sleep(4000); + await auto.toDashboard(page); + }, ourTimeout * 2); + + afterAll(async () => { + // Cleaning + await page.evaluate(async function(studyId, tagId) { + await osparc.data.Resources.fetch('studies', 'delete', { + url: { + "studyId": studyId + } + }, studyId); + await osparc.data.Resources.fetch('tags', 'delete', { + url: { + tagId: tagId + } + }, tagId); + }, studyId, tagId); + page.off('response', responseHandler); + await auto.logOut(page); + }, ourTimeout); + + test('add a tag', async () => { + // Add a tag + await waitAndClick(page, '[osparc-test-id="userMenuBtn"]'); + await waitAndClick(page, '[osparc-test-id="userMenuPreferencesBtn"]'); + await waitAndClick(page, '[osparc-test-id="preferencesTagsTabBtn"]'); + await waitAndClick(page, '[osparc-test-id="addTagBtn"]'); + await utils.typeInInputElement(page, '[qxclass="osparc.form.tag.TagItem"]:last-of-type input[type="text"]', TAG_NAME); + await waitAndClick(page, '[qxclass="osparc.form.tag.TagItem"]:last-of-type [qxclass="osparc.ui.form.FetchButton"]'); + // Check tag was added + await page.waitForFunction(tagName => { + const el = document.querySelector( + '[qxclass="osparc.form.tag.TagItem"]:last-of-type [qxclass="osparc.ui.basic.Tag"]' + ); + return el && el.innerText === tagName; + }, {}, TAG_NAME); + // Close properties + await waitAndClick(page, '[osparc-test-id="preferencesWindowCloseBtn"]'); + }, ourTimeout); + + test('tag shows in filters', async () => { + // Check that tag shows in filter + await waitAndClick(page, '[osparc-test-id="searchBarFilter-textField-study"]'); + await waitAndClick(page, '[osparc-test-id="searchBarFilter-tags-button"]'); + const tagFilterMenu = await page.waitForSelector('[osparc-test-id="searchBarFilter-tags-menu"]:not([style*="display: none"])'); + expect(await tagFilterMenu.evaluate(el => el.innerText)).toContain(TAG_NAME); + }, ourTimeout); + + // wait until card gets unlocked. Tags will anyway be replaced by folder in the coming weeks + test.skip('assign tag and reflect changes', async () => { + await page.waitForSelector( + '[qxclass="osparc.dashboard.GridButtonItem"] > [qxclass="osparc.ui.basic.Thumbnail"]', + { + hidden: true + } + ); + // Assign to study + await waitAndClick(page, '[qxclass="osparc.dashboard.GridButtonItem"] [osparc-test-id="studyItemMenuButton"]'); + await waitAndClick(page, '[osparc-test-id="moreInfoBtn"]'); + await waitAndClick(page, '[osparc-test-id="editStudyEditTagsBtn"]'); + await waitAndClick(page, '[qxclass="osparc.form.tag.TagToggleButton"]'); + await waitAndClick(page, '[osparc-test-id="saveTagsBtn"]'); + // UI displays the change + let displayedTag = await page.waitForSelector('[qxclass="osparc.dashboard.GridButtonItem"] [qxclass="osparc.ui.basic.Tag"]') + await waitAndClick(page, '.qx-service-window[qxclass="osparc.ui.window.Window"] > .qx-workbench-small-cap-captionbar [qxclass="qx.ui.form.Button"]'); + expect(await displayedTag.evaluate(el => el.innerText)).toContain(TAG_NAME); + }, ourTimeout); + + // wait until card gets unlocked. Tags will anyway be replaced by folder in the coming weeks + test.skip('change tag and reflect changes', async () => { + // Change the tag + await waitAndClick(page, '[osparc-test-id="userMenuBtn"]'); + await waitAndClick(page, '[osparc-test-id="userMenuPreferencesBtn"]'); + await waitAndClick(page, '[osparc-test-id="preferencesTagsTabBtn"]'); + await waitAndClick(page, '[qxclass="osparc.form.tag.TagItem"] [qxclass="qx.ui.form.Button"]'); + await utils.clearInput(page, '[qxclass="osparc.form.tag.TagItem"] input[type="text"]'); + await utils.typeInInputElement(page, '[qxclass="osparc.form.tag.TagItem"] input[type="text"]', TAG_NAME_2); + await waitAndClick(page, '[qxclass="osparc.form.tag.TagItem"] [qxclass="osparc.ui.form.FetchButton"]'); + await page.waitForFunction(tagName => { + const el = document.querySelector( + '[qxclass="osparc.form.tag.TagItem"] [qxclass="osparc.ui.basic.Tag"]' + ); + return el && el.innerText === tagName; + }, {}, TAG_NAME_2); + // Close properties + await waitAndClick(page, '[osparc-test-id="preferencesWindowCloseBtn"]'); + // Check that tag name changed in filter and study list + await waitAndClick(page, '[osparc-test-id="searchBarFilter-textField-study"]'); + await waitAndClick(page, '[osparc-test-id="searchBarFilter-tags-button"]'); + const tagFilterMenu = await page.waitForSelector('[osparc-test-id="searchBarFilter-tags-menu"]:not([style*="display: none"])'); + expect(await tagFilterMenu.evaluate(el => el.innerText)).toContain(TAG_NAME_2); + await page.waitForFunction(tagName => { + const el = document.querySelector( + '[qxclass="osparc.dashboard.GridButtonItem"] [qxclass="osparc.ui.basic.Tag"]' + ); + return el && el.innerText === tagName; + }, {}, TAG_NAME_2); + }, ourTimeout); + }); + } +} diff --git a/tests/e2e/tests/tags.tes.js b/tests/e2e/tests/tags.tes.js deleted file mode 100644 index 72d12f2238b8..000000000000 --- a/tests/e2e/tests/tags.tes.js +++ /dev/null @@ -1,156 +0,0 @@ -// OM rename this file and fix the test - -const utils = require('../utils/utils'); -const auto = require('../utils/auto'); -const waitAndClick = require('../utils/utils').waitAndClick; - -describe('tags testing', () => { - const { - user, - pass, - } = utils.getUserAndPass(); - - const TAG_NAME = 'tag_test'; - const TAG_NAME_2 = 'tag_test_2'; - let studyId = null; - let tagId = null; - - /** - * This function records the IDs of the study and tag created in order to later remove them. - */ - const responseHandler = response => { - if (response.url().endsWith('/tags') && response.request().method() === 'POST') { - response.json() - .then(({ - data: { - id - } - }) => { - console.log("Tag created, id", id); - tagId = id; - }); - } - if (response.url().endsWith('/projects') && response.request().method() === 'POST') { - response.json() - .then(({ - data: { - uuid - } - }) => { - console.log("Study created, uuid", uuid); - studyId = uuid; - }); - } - } - - beforeAll(async () => { - page.on('response', responseHandler); - await page.goto(url); - await auto.register(page, user, pass); - // Create new study - const uiConfig = await page.evaluate(async () => await osparc.store.Products.getInstance().fetchUiConfig()); - if ("plusButton" in uiConfig) { - await waitAndClick(page, '[osparc-test-id="newPlusBtn"]'); - } - await waitAndClick(page, '[osparc-test-id="emptyStudyBtn"]'); - // Wait until project is created and Dashboard button is enabled - await utils.sleep(4000); - await auto.toDashboard(page); - }, ourTimeout * 2); - - afterAll(async () => { - // Cleaning - await page.evaluate(async function(studyId, tagId) { - await osparc.data.Resources.fetch('studies', 'delete', { - url: { - "studyId": studyId - } - }, studyId); - await osparc.data.Resources.fetch('tags', 'delete', { - url: { - tagId: tagId - } - }, tagId); - }, studyId, tagId); - page.off('response', responseHandler); - await auto.logOut(page); - }, ourTimeout); - - test('add a tag', async () => { - // Add a tag - await waitAndClick(page, '[osparc-test-id="userMenuBtn"]'); - await waitAndClick(page, '[osparc-test-id="userMenuPreferencesBtn"]'); - await waitAndClick(page, '[osparc-test-id="preferencesTagsTabBtn"]'); - await waitAndClick(page, '[osparc-test-id="addTagBtn"]'); - await utils.typeInInputElement(page, '[qxclass="osparc.form.tag.TagItem"]:last-of-type input[type="text"]', TAG_NAME); - await waitAndClick(page, '[qxclass="osparc.form.tag.TagItem"]:last-of-type [qxclass="osparc.ui.form.FetchButton"]'); - // Check tag was added - await page.waitForFunction(tagName => { - const el = document.querySelector( - '[qxclass="osparc.form.tag.TagItem"]:last-of-type [qxclass="osparc.ui.basic.Tag"]' - ); - return el && el.innerText === tagName; - }, {}, TAG_NAME); - // Close properties - await waitAndClick(page, '[osparc-test-id="preferencesWindowCloseBtn"]'); - }, ourTimeout); - - test('tag shows in filters', async () => { - // Check that tag shows in filter - await waitAndClick(page, '[osparc-test-id="searchBarFilter-textField-study"]'); - await waitAndClick(page, '[osparc-test-id="searchBarFilter-tags-button"]'); - const tagFilterMenu = await page.waitForSelector('[osparc-test-id="searchBarFilter-tags-menu"]:not([style*="display: none"])'); - expect(await tagFilterMenu.evaluate(el => el.innerText)).toContain(TAG_NAME); - }, ourTimeout); - - // wait until card gets unlocked. Tags will anyway be replaced by folder in the coming weeks - test.skip('assign tag and reflect changes', async () => { - await page.waitForSelector( - '[qxclass="osparc.dashboard.GridButtonItem"] > [qxclass="osparc.ui.basic.Thumbnail"]', - { - hidden: true - } - ); - // Assign to study - await waitAndClick(page, '[qxclass="osparc.dashboard.GridButtonItem"] [osparc-test-id="studyItemMenuButton"]'); - await waitAndClick(page, '[osparc-test-id="moreInfoBtn"]'); - await waitAndClick(page, '[osparc-test-id="editStudyEditTagsBtn"]'); - await waitAndClick(page, '[qxclass="osparc.form.tag.TagToggleButton"]'); - await waitAndClick(page, '[osparc-test-id="saveTagsBtn"]'); - // UI displays the change - let displayedTag = await page.waitForSelector('[qxclass="osparc.dashboard.GridButtonItem"] [qxclass="osparc.ui.basic.Tag"]') - await waitAndClick(page, '.qx-service-window[qxclass="osparc.ui.window.Window"] > .qx-workbench-small-cap-captionbar [qxclass="qx.ui.form.Button"]'); - expect(await displayedTag.evaluate(el => el.innerText)).toContain(TAG_NAME); - }, ourTimeout); - - // wait until card gets unlocked. Tags will anyway be replaced by folder in the coming weeks - test.skip('change tag and reflect changes', async () => { - // Change the tag - await waitAndClick(page, '[osparc-test-id="userMenuBtn"]'); - await waitAndClick(page, '[osparc-test-id="userMenuPreferencesBtn"]'); - await waitAndClick(page, '[osparc-test-id="preferencesTagsTabBtn"]'); - await waitAndClick(page, '[qxclass="osparc.form.tag.TagItem"] [qxclass="qx.ui.form.Button"]'); - await utils.clearInput(page, '[qxclass="osparc.form.tag.TagItem"] input[type="text"]'); - await utils.typeInInputElement(page, '[qxclass="osparc.form.tag.TagItem"] input[type="text"]', TAG_NAME_2); - await waitAndClick(page, '[qxclass="osparc.form.tag.TagItem"] [qxclass="osparc.ui.form.FetchButton"]'); - await page.waitForFunction(tagName => { - const el = document.querySelector( - '[qxclass="osparc.form.tag.TagItem"] [qxclass="osparc.ui.basic.Tag"]' - ); - return el && el.innerText === tagName; - }, {}, TAG_NAME_2); - // Close properties - await waitAndClick(page, '[osparc-test-id="preferencesWindowCloseBtn"]'); - // Check that tag name changed in filter and study list - await waitAndClick(page, '[osparc-test-id="searchBarFilter-textField-study"]'); - await waitAndClick(page, '[osparc-test-id="searchBarFilter-tags-button"]'); - const tagFilterMenu = await page.waitForSelector('[osparc-test-id="searchBarFilter-tags-menu"]:not([style*="display: none"])'); - expect(await tagFilterMenu.evaluate(el => el.innerText)).toContain(TAG_NAME_2); - await page.waitForFunction(tagName => { - const el = document.querySelector( - '[qxclass="osparc.dashboard.GridButtonItem"] [qxclass="osparc.ui.basic.Tag"]' - ); - return el && el.innerText === tagName; - }, {}, TAG_NAME_2); - }, ourTimeout); -}); diff --git a/tests/e2e/tests/testsToRunSequentially.test.js b/tests/e2e/tests/testsToRunSequentially.test.js new file mode 100644 index 000000000000..d8b6d24c519f --- /dev/null +++ b/tests/e2e/tests/testsToRunSequentially.test.js @@ -0,0 +1,12 @@ +const { checkUrl } = require('./url.js'); +const { checkMetadata } = require('./title'); +const { registerAndLogOut } = require('./register'); +const { startupCalls } = require('./startupCalls'); + + +describe('Sequentially run tests', () => { + checkUrl(); + checkMetadata(); + registerAndLogOut(); + startupCalls(); +}); diff --git a/tests/e2e/tests/title.js b/tests/e2e/tests/title.js new file mode 100644 index 000000000000..4f16b285eb74 --- /dev/null +++ b/tests/e2e/tests/title.js @@ -0,0 +1,42 @@ +const appMetadata = require('../../../services/static-webserver/client/scripts/apps_metadata.json') + +module.exports = { + checkMetadata: () => { + describe('Check Metadata', () => { + beforeAll(async () => { + console.log("Start:", new Date().toUTCString()); + + await page.goto(url); + }, ourTimeout); + + afterAll(() => { + console.log("End:", new Date().toUTCString()); + }, ourTimeout); + + test('Check site metadata', async () => { + const title = await page.title(); + expect(title).toContain("PARC"); + + // oSPARC ([0]) is the product served by default + const replacements = appMetadata["applications"][0]["replacements"]; + + const description = await page.$$eval("head > meta[name='description']", descriptions => { + return descriptions[0].content; + }); + expect(description).toBe(replacements["replace_me_og_description"]); + + // Open Graph metadata + const ogTitle = await page.$$eval("head > meta[property='og:title']", ogTitles => { + return ogTitles[0].content; + }); + expect(ogTitle).toBe(replacements["replace_me_og_title"]); + + const ogDescription = await page.$$eval("head > meta[property='og:description']", ogDescriptions => { + return ogDescriptions[0].content; + }); + expect(ogDescription).toBe(replacements["replace_me_og_description"]); + + }, 20000); + }); + } +} diff --git a/tests/e2e/tests/title.test.js b/tests/e2e/tests/title.test.js deleted file mode 100644 index 947db9523456..000000000000 --- a/tests/e2e/tests/title.test.js +++ /dev/null @@ -1,30 +0,0 @@ -const appMetadata = require('../../../services/static-webserver/client/scripts/apps_metadata.json') - -beforeAll(async () => { - await page.goto(url); -}, ourTimeout); - -test('Check site title', async () => { - const title = await page.title(); - expect(title).toContain("PARC"); - - // oSPARC ([0]) is the product served by default - const replacements = appMetadata["applications"][0]["replacements"]; - - const description = await page.$$eval("head > meta[name='description']", descriptions => { - return descriptions[0].content; - }); - expect(description).toBe(replacements["replace_me_og_description"]); - - // Open Graph metadata - const ogTitle = await page.$$eval("head > meta[property='og:title']", ogTitles => { - return ogTitles[0].content; - }); - expect(ogTitle).toBe(replacements["replace_me_og_title"]); - - const ogDescription = await page.$$eval("head > meta[property='og:description']", ogDescriptions => { - return ogDescriptions[0].content; - }); - expect(ogDescription).toBe(replacements["replace_me_og_description"]); - -}, 20000); diff --git a/tests/e2e/tests/url.js b/tests/e2e/tests/url.js new file mode 100644 index 000000000000..d44092edf20a --- /dev/null +++ b/tests/e2e/tests/url.js @@ -0,0 +1,20 @@ +module.exports = { + checkUrl: () => { + describe('Check URL', () => { + beforeAll(async () => { + console.log("Start:", new Date().toUTCString()); + + await page.goto(url); + }, ourTimeout); + + afterAll(async () => { + console.log("End:", new Date().toUTCString()); + }, ourTimeout); + + test('Check site url', async () => { + const url2 = page.url(); + expect(url2).toBe(url); + }, 20000); + }); + } +} diff --git a/tests/e2e/tests/url.test.js b/tests/e2e/tests/url.test.js deleted file mode 100644 index 13380177eeb4..000000000000 --- a/tests/e2e/tests/url.test.js +++ /dev/null @@ -1,8 +0,0 @@ -beforeAll(async () => { - await page.goto(url); -}, ourTimeout); - -test('Check site url', async () => { - const url2 = page.url(); - expect(url2).toBe(url); -}, 20000);