Skip to content

Commit

Permalink
Merge branch 'develop' into SS-1141-bump-versions-for-custom-err-pages
Browse files Browse the repository at this point in the history
  • Loading branch information
churnikov authored Nov 29, 2024
2 parents dd75942 + 3f61cb4 commit 4cf9be2
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 86 deletions.
136 changes: 131 additions & 5 deletions cypress/e2e/ui-tests/test-deploy-app.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@ describe("Test deploying app", () => {
it("can deploy a project and public app using the custom app chart", { defaultCommandTimeout: defaultCmdTimeoutMs }, () => {
// Names of objects to create
const project_name = "e2e-deploy-app-test"
const app_name_project = "e2e-streamlit-example-project"
const app_name_public = "e2e-streamlit-example-public"
const app_name_public_2 = "e2e-streamlit-example-2-public"
const app_description = "e2e-streamlit-description"
const app_description_2 = "e2e-streamlit-2-description"
const app_name_project = "e2e-custom-example-project"
const app_name_public = "e2e-custom-example-public"
const app_name_public_2 = "e2e-custom-example-2-public"
const app_description = "e2e-custom-description"
const app_description_2 = "e2e-custom-2-description"
const image_name = "ghcr.io/scilifelabdatacentre/example-streamlit:latest"
const image_name_2 = "ghcr.io/scilifelabdatacentre/example-streamlit:230921-1443"
const image_port = "8501"
Expand Down Expand Up @@ -470,6 +470,132 @@ describe("Test deploying app", () => {
}
})

it("can deploy a gradio app", { defaultCommandTimeout: defaultCmdTimeoutMs }, () => {
// Simple test to create and delete a Gradio app
// Names of objects to create
const project_name = "e2e-deploy-app-test"
const app_name = "e2e-gradio-example"
const app_description = "e2e-gradio-description"
const source_code_url = "https://doi.org/example"
const image_name = "ghcr.io/scilifelabdatacentre/gradio-flower-classification:20241118-174426"
const image_port = "7860"
const createResources = Cypress.env('create_resources');
const app_type = "Gradio App"

if (createResources === true) {
// Create Gradio app
cy.logf("Creating a gradio app", Cypress.currentTest)
cy.visit("/projects/")
cy.contains('.card-title', project_name).parents('.card-body').siblings('.card-footer').find('a:contains("Open")').first().click()
cy.get('div.card-body:contains("' + app_type + '")').find('a:contains("Create")').click()
cy.get('#id_name').type(app_name)
cy.get('#id_description').type(app_description)
cy.get('#id_access').select('Public')
cy.get('#id_source_code_url').type(source_code_url)
cy.get('#id_image').clear().type(image_name)
cy.get('#id_port').clear().type(image_port)
cy.get('#submit-id-submit').contains('Submit').click()
// Back on project page
cy.url().should("not.include", "/apps/settings")
cy.get('h3').should('have.text', project_name);
// check that the app was created
verifyAppStatus(app_name, "Running", "public")

// Verify Gradio app values
cy.logf("Checking that all dash app settings were saved", Cypress.currentTest)
cy.visit("/projects/")
cy.contains('.card-title', project_name).parents('.card-body').siblings('.card-footer').find('a:contains("Open")').first().click()
cy.get('tr:contains("' + app_name + '")').find('i.bi-three-dots-vertical').click()
cy.get('tr:contains("' + app_name + '")').find('a').contains('Settings').click()
cy.get('#id_name').should('have.value', app_name)
cy.get('#id_description').should('have.value', app_description)
cy.get('#id_access').find(':selected').should('contain', 'Public')
cy.get('#id_image').should('have.value', image_name)
cy.get('#id_port').should('have.value', image_port)

// Delete the Gradio app
cy.logf("Deleting the gradio app", Cypress.currentTest)
cy.visit("/projects/")
cy.contains('.card-title', project_name).parents('.card-body').siblings('.card-footer').find('a:contains("Open")').first().click()
cy.get('tr:contains("' + app_name + '")').find('i.bi-three-dots-vertical').click()
cy.get('tr:contains("' + app_name + '")').find('a.confirm-delete').click()
cy.get('button').contains('Delete').click()
verifyAppStatus(app_name, "Deleted", "")

// check that the app is not visible under public apps
cy.visit('/apps/')
cy.get("title").should("have.text", "Apps and models | SciLifeLab Serve (beta)")
cy.get('h3').should('contain', 'Public applications and models')
cy.contains('h5.card-title', app_name).should('not.exist')

} else {
cy.logf('Skipped because create_resources is not true', Cypress.currentTest);
}
})

it("can deploy a streamlit app", { defaultCommandTimeout: defaultCmdTimeoutMs }, () => {
// Simple test to create and delete a Streamlit app
// Names of objects to create
const project_name = "e2e-deploy-app-test"
const app_name = "e2e-streamlit-example"
const app_description = "e2e-streamlit-description"
const source_code_url = "https://doi.org/example"
const image_name = "ghcr.io/scilifelabdatacentre/streamlit-image-to-smiles:20241112-183549"
const image_port = "8501"
const createResources = Cypress.env('create_resources');
const app_type = "Streamlit App"

if (createResources === true) {
// Create Streamlit app
cy.logf("Creating a streamlit app", Cypress.currentTest)
cy.visit("/projects/")
cy.contains('.card-title', project_name).parents('.card-body').siblings('.card-footer').find('a:contains("Open")').first().click()
cy.get('div.card-body:contains("' + app_type + '")').find('a:contains("Create")').click()
cy.get('#id_name').type(app_name)
cy.get('#id_description').type(app_description)
cy.get('#id_access').select('Public')
cy.get('#id_source_code_url').type(source_code_url)
cy.get('#id_image').clear().type(image_name)
cy.get('#id_port').clear().type(image_port)
cy.get('#submit-id-submit').contains('Submit').click()
// Back on project page
cy.url().should("not.include", "/apps/settings")
cy.get('h3').should('have.text', project_name);
// check that the app was created
verifyAppStatus(app_name, "Running", "public")

// Verify Streamlit app values
cy.logf("Checking that all dash app settings were saved", Cypress.currentTest)
cy.visit("/projects/")
cy.contains('.card-title', project_name).parents('.card-body').siblings('.card-footer').find('a:contains("Open")').first().click()
cy.get('tr:contains("' + app_name + '")').find('i.bi-three-dots-vertical').click()
cy.get('tr:contains("' + app_name + '")').find('a').contains('Settings').click()
cy.get('#id_name').should('have.value', app_name)
cy.get('#id_description').should('have.value', app_description)
cy.get('#id_access').find(':selected').should('contain', 'Public')
cy.get('#id_image').should('have.value', image_name)
cy.get('#id_port').should('have.value', image_port)

// Delete the Streamlit app
cy.logf("Deleting the dash app", Cypress.currentTest)
cy.visit("/projects/")
cy.contains('.card-title', project_name).parents('.card-body').siblings('.card-footer').find('a:contains("Open")').first().click()
cy.get('tr:contains("' + app_name + '")').find('i.bi-three-dots-vertical').click()
cy.get('tr:contains("' + app_name + '")').find('a.confirm-delete').click()
cy.get('button').contains('Delete').click()
verifyAppStatus(app_name, "Deleted", "")

// check that the app is not visible under public apps
cy.visit('/apps/')
cy.get("title").should("have.text", "Apps and models | SciLifeLab Serve (beta)")
cy.get('h3').should('contain', 'Public applications and models')
cy.contains('h5.card-title', app_name).should('not.exist')

} else {
cy.logf('Skipped because create_resources is not true', Cypress.currentTest);
}
})

it("can modify app settings resulting in NO k8s redeployment shows correct app status", { defaultCommandTimeout: defaultCmdTimeoutMs }, () => {
// An advanced test to verify user can modify app settings such as the name and description
// Names of objects to create
Expand Down
97 changes: 18 additions & 79 deletions cypress/e2e/ui-tests/test-project-as-contributor.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,24 @@ describe("Test project contributor user functionality", () => {
cy.contains('.card-title', project_name).parents('.card-body').siblings('.card-footer').find('a:contains("Open")').first().click()
cy.get('.card-text').should('contain', project_description_2)

cy.logf("Check that creating another project with same existing project name will create an error", Cypress.currentTest)
cy.visit("/projects/")
cy.get("a").contains('New project').click()
cy.get("a").contains('Create').first().click()
cy.get('input[name=name]').type(project_name) // same name used before
cy.get('textarea[name=description]').type(project_description)
cy.get("input[name=save]").contains('Create project').click() // should generate an error
// Check that the error message is displayed
cy.get('#flash-msg')
.should('be.visible')
.and('have.class', 'alert-danger')
.and('contain.text', `Project cannot be created because a project with name '${project_name}' already exists.`);
cy.logf("Error is successfully generated when trying to create a new project with the same existing project name", Cypress.currentTest)

// go back to the previously created project
cy.visit("/projects/")
cy.contains('.card-title', project_name).parents('.card-body').siblings('.card-footer').find('a.btn').contains('Open').click()

cy.logf("Delete the project from the settings menu", Cypress.currentTest)
cy.get('[data-cy="settings"]').click()
cy.get('a').contains("Delete").click()
Expand All @@ -117,85 +135,6 @@ describe("Test project contributor user functionality", () => {
})
})

// This test cannot run properly in GitHub workflows because there is an issue with minio creation there. Therefore, it should be run locally to make sure things work. For GitHub, skipping it.

// TODO: When models are launched, make sure that this test is activated
it.skip("can create a new project with ML serving template, open settings, delete from settings", { defaultCommandTimeout: defaultCmdTimeoutMs }, () => {

// Names of objects to create
const project_name = "e2e-create-ml-proj-test"
const project_title_name = project_name + " | SciLifeLab Serve (beta)"

cy.visit("/projects/")
cy.get("title").should("have.text", "My projects | SciLifeLab Serve (beta)")

// Click button for UI to create a new project
cy.get("a").contains('New project').click()
cy.url().should("include", "projects/templates")
cy.get('h3').should('contain', 'New project')

// Next click button to create a new blank project
cy.get(".card-footer").last().contains("Create").click()
cy.url().should("include", "projects/create/?template=")
cy.get('h3').should('contain', 'New project')

// Fill in the options for creating a new blank project
cy.get('input[name=name]').type(project_name)
cy.get('textarea[name=description]').type("A test project created by an e2e test.")
cy.get("input[name=save]").contains('Create project').click()
cy.wait(5000) // sometimes it takes a while to create a project
.then((href) => {
cy.logf(href, Cypress.currentTest)
cy.reload()
cy.get("title").should("have.text", project_title_name)
cy.get('h3').should('contain', project_name)

// Check that the correct deployment options are available
cy.get('.card-header').find('h5').should('contain', 'Develop')
cy.get('.card-header').find('h5').should('contain', 'Serve')
cy.get('.card-header').find('h5').should('contain', 'Models')
cy.get('.card-header').find('h5').should('not.contain', 'Additional options [admins only]')

// Section Models - Machine Learning Models
// Navigate to the create models view and cancel back again
cy.get("div#models").first("h5").should("contain", "Machine Learning Models")
cy.get("div#models").find("a.btn").click()
.then((href) => {
cy.url().should("include", "models/create")
cy.get('h3').should("contain", "Create Model Object")
cy.get("button").contains("Cancel").click()
.then((href) => {
cy.get('h3').should("contain", project_name)
})
})

// Check that project settings are available
cy.get('[data-cy="settings"]').click()
cy.url().should("include", "settings")
cy.get('h3').should('contain', 'Project settings')

// Check that the correct project settings are visible (i.e. no extra settings)
cy.get('.list-group').find('a').should('contain', 'Access')
cy.get('.list-group').find('a').should('not.contain', 'S3 storage')
cy.get('.list-group').find('a').should('not.contain', 'MLFlow')
cy.get('.list-group').find('a').should('not.contain', 'Flavors')
cy.get('.list-group').find('a').should('not.contain', 'Environments')

// Delete the project from the settings menu
cy.get('a').contains("Delete").click()
.then((href) => {
cy.get('div#delete').should('have.css', 'display', 'block')
cy.get('#id_delete_button').parent().parent().find('button').contains('Delete').click()
.then((href) => {
cy.get('div#deleteModal').should('have.css', 'display', 'block')
cy.get('div#deleteModal').find('button').contains('Confirm').click()
})
cy.contains(project_name).should('not.exist')

})
})
})

it("can delete a project from projects overview", { defaultCommandTimeout: defaultCmdTimeoutMs }, () => {

// Names of objects to create
Expand Down
29 changes: 27 additions & 2 deletions cypress/e2e/ui-tests/test-superuser-functionality.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ describe("Test superuser access", () => {
// Names of objects to create
const project_name = "e2e-create-default-proj-test"
const project_description = "A test project created by an e2e test."
const project_description_duplicate = "A test project with an existing project name"
const project_description_2 = "An alternative project description created by an e2e test."

cy.visit("/projects/")
Expand All @@ -65,12 +66,10 @@ describe("Test superuser access", () => {
cy.get('input[name=name]').type(project_name)
cy.get('textarea[name=description]').type(project_description)
cy.get("input[name=save]").contains('Create project').click()
//cy.wait(5000) // sometimes it takes a while to create a project. Not needed because of cypress retryability.

cy.get('h3', {timeout: longCmdTimeoutMs}).should('contain', project_name)
cy.get('.card-text').should('contain', project_description)


cy.logf("Checking that project settings are available", Cypress.currentTest)
cy.get('[data-cy="settings"]').click()
cy.url().should("include", "settings")
Expand All @@ -88,6 +87,32 @@ describe("Test superuser access", () => {
cy.contains('.card-title', project_name).parents('.card-body').siblings('.card-footer').find('a:contains("Open")').first().click()
cy.get('.card-text').should('contain', project_description_2)

cy.logf("Check that creating another project with same existing project name will work for a superuser", Cypress.currentTest)
cy.visit("/projects/")
cy.get("a").contains('New project').click()
cy.get("a").contains('Create').first().click()
cy.get('input[name=name]').type(project_name) // this name already exists
cy.get('textarea[name=description]').type(project_description_duplicate) // this will be used to ensure to delete it
cy.get("input[name=save]").contains('Create project').click()
cy.get('h3', {timeout: longCmdTimeoutMs}).should('contain', project_name)
cy.get('.card-text').should('contain', project_description_duplicate) // checking that project creation succeeded
// deleting the project with the duplicate name
cy.get('[data-cy="settings"]').click()
cy.get('a').contains("Delete").click()
.then((href) => {
cy.get('div#delete').should('have.css', 'display', 'block')
cy.get('#id_delete_button').parent().parent().find('button').contains('Delete').click()
.then((href) => {
cy.get('div#deleteModal').should('have.css', 'display', 'block')
cy.get('div#deleteModal').find('button').contains('Confirm').click()
})
// checking that the project with the duplicate name has been deleted
cy.visit("/projects/")
cy.contains(project_description_duplicate).should('not.exist')
})
// going to the previously created project's page
cy.contains('.card-title', project_name).parents('.card-body').siblings('.card-footer').find('a.btn').contains('Open').click()

cy.logf("Deleting the project from the settings menu", Cypress.currentTest)
cy.get('[data-cy="settings"]').click()
cy.get('a').contains("Delete").click()
Expand Down

0 comments on commit 4cf9be2

Please sign in to comment.