diff --git a/test/e2e/support/commands.js b/test/e2e/support/commands.js index 0bd882659..e46682761 100644 --- a/test/e2e/support/commands.js +++ b/test/e2e/support/commands.js @@ -137,15 +137,55 @@ Cypress.Commands.add("clearupDeployments", (subdir) => { cy.exec(`rm -rf content-workspace/${subdir}/.posit`); }); -Cypress.Commands.add("expandWildcardFile", (projectName, wildCardPath) => { - const workingDir = `content-workspace/${projectName}/.posit/publish`; +// returns +// config: { +// name: string, +// path: string, +// }, +// contentRecord: { +// name: string, +// path: string, +// } +Cypress.Commands.add("getPublisherTomlFilePaths", (projectDir) => { + let configTargetDir = `content-workspace/${projectDir}/.posit/publish`; + let configFileName = ""; + let configFilePath = ""; + let contentRecordTargetDir = `content-workspace/${projectDir}/.posit/publish/deployments`; + let contentRecordFileName = ""; + let contentRecordFilePath = ""; + + cy.expandWildcardFile(configTargetDir, "*.toml") + .then((configFile) => { + configFileName = configFile; + configFilePath = `${configTargetDir}/${configFile}`; + }) + .expandWildcardFile(contentRecordTargetDir, "*.toml") + .then((contentRecordFile) => { + contentRecordFileName = contentRecordFile; + contentRecordFilePath = `${contentRecordTargetDir}/${contentRecordFile}`; + }) + .then(() => { + return { + config: { + name: configFileName, + path: configFilePath, + }, + contentRecord: { + name: contentRecordFileName, + path: contentRecordFilePath, + }, + }; + }); +}); + +Cypress.Commands.add("expandWildcardFile", (targetDir, wildCardPath) => { return cy .exec("pwd") .then((result) => { return cy.log("CWD", result.stdout); }) .then(() => { - const cmd = `cd ${workingDir} && file=$(echo ${wildCardPath}) && echo $file`; + const cmd = `cd ${targetDir} && file=$(echo ${wildCardPath}) && echo $file`; return cy.exec(cmd); }) .then((result) => { @@ -157,31 +197,23 @@ Cypress.Commands.add("expandWildcardFile", (projectName, wildCardPath) => { }); Cypress.Commands.add("savePublisherFile", (filePath, jsonObject) => { - const projectFilePath = `content-workspace/${filePath}`; return cy .exec("pwd") .then((result) => { return cy .log("savePublisherFile CWD", result.stdout) - .log("filePath", projectFilePath); + .log("filePath", filePath); }) .then(() => { const tomlString = stringify(jsonObject); - return cy.writeFile(projectFilePath, tomlString); + return cy.writeFile(filePath, tomlString); }); }); -Cypress.Commands.add("loadProjectConfigFile", (projectName, configName) => { - const projectConfigPath = `content-workspace/${projectName}/.posit/publish/${configName}`; - // Do not fail on non-zero exit this time, we can provide a better error +Cypress.Commands.add("loadTomlFile", (filePath) => { return cy - .exec("pwd") - .then((result) => { - return cy - .log("projectConfigPath", projectConfigPath) - .log("loadProjectConfigFile CWD", result.stdout); - }) - .exec(`cat ${projectConfigPath}`, { failOnNonZeroExit: false }) + .log("filePath", filePath) + .exec(`cat ${filePath}`, { failOnNonZeroExit: false }) .then((result) => { if (result.code === 0 && result.stdout) { return parse(result.stdout); @@ -190,32 +222,6 @@ Cypress.Commands.add("loadProjectConfigFile", (projectName, configName) => { }); }); -Cypress.Commands.add("loadProjectDeploymentFile", (projectName) => { - const projectDeploymentPath = `content-workspace/${projectName}/.posit/publish/deployments/deployment-*.toml`; - // Do not fail on non-zero exit this time, we can provide a better error - return cy - .exec(`cat ${projectDeploymentPath}`, { failOnNonZeroExit: false }) - .then((result) => { - if (result.code === 0 && result.stdout) { - return parse(result.stdout); - } - throw new Error(`Could not load project deployment. ${result.stderr}`); - }); -}); - -Cypress.Commands.add("loadProjectDeploymentFile", (projectName) => { - const projectDeploymentPath = `content-workspace/${projectName}/.posit/publish/deployments/deployment-*.toml`; - // Do not fail on non-zero exit this time, we can provide a better error - return cy - .exec(`cat ${projectDeploymentPath}`, { failOnNonZeroExit: false }) - .then((result) => { - if (result.code === 0 && result.stdout) { - return parse(result.stdout); - } - throw new Error(`Could not load project deployment. ${result.stderr}`); - }); -}); - // Performs the full set of reset commands we typically use before executing our tests Cypress.Commands.add("resetConnect", () => { cy.clearupDeployments(); diff --git a/test/e2e/support/sequences.js b/test/e2e/support/sequences.js index 450157925..12824d258 100644 --- a/test/e2e/support/sequences.js +++ b/test/e2e/support/sequences.js @@ -1,12 +1,26 @@ // Copyright (C) 2025 by Posit Software, PBC. +// tomlCallback interface = func( +// { +// config: { +// name: string, +// path: string, +// contents: {}, +// }, +// contentRecord: { +// name: string, +// path: string, +// contents: {}, +// } +// }) + Cypress.Commands.add( "createDeployment", ( projectDir, // string entrypointFile, // string title, // string - verifyConfigCallback, // func({ fileName: configFileName, contents: contents}) + verifyTomlCallback, // func({config: { filename: string, contents: {},}, contentRecord: { filename: string, contents: {}}) ) => { // Temporarily ignore uncaught exception due to a vscode worker being cancelled at some point. cy.on("uncaught:exception", () => false); @@ -84,19 +98,34 @@ Cypress.Commands.add( .click(); return cy - .expandWildcardFile(projectDir, `${title}-*.toml`) - .then((configFileName) => { - cy.loadProjectConfigFile(projectDir, configFileName).then( - (contents) => { - return { - fileName: configFileName, - contents: contents, - }; + .getPublisherTomlFilePaths(projectDir) + .then((filePaths) => { + let result = { + config: { + name: filePaths.config.name, + path: filePaths.config.path, + contents: {}, + }, + contentRecord: { + name: filePaths.contentRecord.name, + path: filePaths.contentRecord.path, + contents: {}, }, - ); + }; + cy.loadTomlFile(filePaths.config.path) + .then((config) => { + result.config.contents = config; + }) + .loadTomlFile(filePaths.contentRecord.path) + .then((contentRecord) => { + result.contentRecord.contents = contentRecord; + }) + .then(() => { + return result; + }); }) - .then((configFile) => { - return verifyConfigCallback(configFile); + .then((tomlFiles) => { + return verifyTomlCallback(tomlFiles); }); }, ); diff --git a/test/e2e/tests/deployments.cy.js b/test/e2e/tests/deployments.cy.js index 9e0840afd..fb1eafac4 100644 --- a/test/e2e/tests/deployments.cy.js +++ b/test/e2e/tests/deployments.cy.js @@ -9,33 +9,35 @@ describe("Deployments Section", () => { }); it("Static Content Deployment", () => { - cy.createDeployment("static", "index.html", "static", (configFile) => { - expect(configFile.contents.title).to.equal("static"); - expect(configFile.contents.type).to.equal("html"); - expect(configFile.contents.entrypoint).to.equal("index.html"); - expect(configFile.contents.files[0]).to.equal("/index.html"); - expect(configFile.contents.files[1]).to.equal( - `/.posit/publish/${configFile.fileName}`, + cy.createDeployment("static", "index.html", "static", (tomlFiles) => { + const config = tomlFiles.config.contents; + expect(config.title).to.equal("static"); + expect(config.type).to.equal("html"); + expect(config.entrypoint).to.equal("index.html"); + expect(config.files[0]).to.equal("/index.html"); + expect(config.files[1]).to.equal( + `/.posit/publish/${tomlFiles.config.name}`, ); - expect(configFile.contents.files[2]).to.match( - /\/.posit\/publish\/deployments\/deployment-[A-Z0-9]{4}\.toml/, + expect(config.files[2]).to.equal( + `/.posit/publish/deployments/${tomlFiles.contentRecord.name}`, ); }).deployCurrentlySelected(); }); // Unable to run this, as the docker image for the code server does not have R installed. it.skip("ShinyApp Content Deployment", () => { - cy.createDeployment("shinyapp", "app.R", "ShinyApp", (configFile) => { - expect(configFile.contents.title).to.equal("ShinyApp"); - expect(configFile.contents.type).to.equal("r-shiny"); - expect(configFile.contents.entrypoint).to.equal("app.R"); - expect(configFile.contents.files[0]).to.equal("/app.R"); - expect(configFile.contents.files[1]).to.equal("/renv.lock"); - expect(configFile.contents.files[2]).to.equal( - `/.posit/publish/${configFile.fileName}`, + cy.createDeployment("shinyapp", "app.R", "ShinyApp", (tomlFiles) => { + const config = tomlFiles.config.contents; + expect(config.title).to.equal("ShinyApp"); + expect(config.type).to.equal("r-shiny"); + expect(config.entrypoint).to.equal("app.R"); + expect(config.files[0]).to.equal("/app.R"); + expect(config.files[1]).to.equal("/renv.lock"); + expect(config.files[2]).to.equal( + `/.posit/publish/${tomlFiles.config.name}`, ); - expect(configFile.contents.files[3]).to.match( - /\/.posit\/publish\/deployments\/deployment-[A-Z0-9]{4}\.toml/, + expect(config.files[3]).to.equal( + `/.posit/publish/deployments/${tomlFiles.contentRecord.name}`, ); }).deployCurrentlySelected(); }); diff --git a/test/e2e/tests/embedded-deployments.cy.js b/test/e2e/tests/embedded-deployments.cy.js index 670732f9f..b24753cae 100644 --- a/test/e2e/tests/embedded-deployments.cy.js +++ b/test/e2e/tests/embedded-deployments.cy.js @@ -14,28 +14,27 @@ describe("Create Deployments", () => { ".", "simple.py", "fastapi-base-directory", - (configFile) => { - expect(configFile.contents.title).to.equal("fastapi-base-directory"); - expect(configFile.contents.type).to.equal("python-fastapi"); - expect(configFile.contents.entrypoint).to.equal("simple.py"); - expect(configFile.contents.files[0]).to.equal("/simple.py"); - expect(configFile.contents.files[1]).to.equal("/requirements.txt"); - expect(configFile.contents.files[2]).to.equal( - `/.posit/publish/${configFile.fileName}`, + (tomlFiles) => { + const config = tomlFiles.config.contents; + expect(config.title).to.equal("fastapi-base-directory"); + expect(config.type).to.equal("python-fastapi"); + expect(config.entrypoint).to.equal("simple.py"); + expect(config.files[0]).to.equal("/simple.py"); + expect(config.files[1]).to.equal("/requirements.txt"); + expect(config.files[2]).to.equal( + `/.posit/publish/${tomlFiles.config.name}`, ); - // /\/.posit\/publish\/fastapi-base-directory-[A-Z0-9]{4}\.toml/, - // ); - expect(configFile.contents.files[3]).to.match( - /\/.posit\/publish\/deployments\/deployment-[A-Z0-9]{4}\.toml/, + expect(config.files[3]).to.equal( + `/.posit/publish/deployments/${tomlFiles.contentRecord.name}`, ); - return configFile; + return tomlFiles; }, ) - .then((configFile) => { - configFile.contents.python.version = "3.11.3"; + .then((tomlFiles) => { + tomlFiles.config.contents.python.version = "3.11.3"; return cy.savePublisherFile( - `.posit/publish/${configFile.fileName}`, - configFile.contents, + tomlFiles.config.path, + tomlFiles.config.contents, ); }) .then(() => { @@ -49,28 +48,27 @@ describe("Create Deployments", () => { "fastapi-simple", "fastapi-main.py", "fastapi-sub-directory", - (configFile) => { - expect(configFile.contents.title).to.equal("fastapi-sub-directory"); - expect(configFile.contents.type).to.equal("python-fastapi"); - expect(configFile.contents.entrypoint).to.equal("fastapi-main.py"); - expect(configFile.contents.files[0]).to.equal("/fastapi-main.py"); - expect(configFile.contents.files[1]).to.equal("/requirements.txt"); - expect(configFile.contents.files[2]).to.equal( - `/.posit/publish/${configFile.fileName}`, + (tomlFiles) => { + const config = tomlFiles.config.contents; + expect(config.title).to.equal("fastapi-sub-directory"); + expect(config.type).to.equal("python-fastapi"); + expect(config.entrypoint).to.equal("fastapi-main.py"); + expect(config.files[0]).to.equal("/fastapi-main.py"); + expect(config.files[1]).to.equal("/requirements.txt"); + expect(config.files[2]).to.equal( + `/.posit/publish/${tomlFiles.config.name}`, ); - // /\/.posit\/publish\/fastapi-base-directory-[A-Z0-9]{4}\.toml/, - // ); - expect(configFile.contents.files[3]).to.match( - /\/.posit\/publish\/deployments\/deployment-[A-Z0-9]{4}\.toml/, + expect(config.files[3]).to.equal( + `/.posit/publish/deployments/${tomlFiles.contentRecord.name}`, ); - return configFile; + return tomlFiles; }, ) - .then((configFile) => { - configFile.contents.python.version = "3.11.3"; + .then((tomlFiles) => { + tomlFiles.config.contents.python.version = "3.11.3"; return cy.savePublisherFile( - `fastapi-simple/.posit/publish/${configFile.fileName}`, - configFile.contents, + tomlFiles.config.path, + tomlFiles.config.contents, ); }) .then(() => {