From 6323a73a602ac9d35480b08cc1be4a2d4f661072 Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Thu, 23 Apr 2026 22:42:51 +0000 Subject: [PATCH 1/2] feat: add workflow execution samples with and without arguments --- workflows/quickstart/executeWithArguments.js | 97 ++++++++++++++++ workflows/quickstart/executeWithArguments.ts | 99 ++++++++++++++++ .../quickstart/executeWithoutArguments.js | 89 ++++++++++++++ .../quickstart/executeWithoutArguments.ts | 89 ++++++++++++++ workflows/quickstart/package.json | 5 +- .../quickstart/test/executeWorkflow.test.js | 109 ++++++++++++++++++ .../quickstart/test/executeWorkflow.test.ts | 108 +++++++++++++++++ workflows/quickstart/test/quickstart.test.js | 24 ++-- workflows/quickstart/test/quickstart.test.ts | 32 ++--- workflows/quickstart/tsconfig.json | 4 +- 10 files changed, 632 insertions(+), 24 deletions(-) create mode 100644 workflows/quickstart/executeWithArguments.js create mode 100644 workflows/quickstart/executeWithArguments.ts create mode 100644 workflows/quickstart/executeWithoutArguments.js create mode 100644 workflows/quickstart/executeWithoutArguments.ts create mode 100644 workflows/quickstart/test/executeWorkflow.test.js create mode 100644 workflows/quickstart/test/executeWorkflow.test.ts diff --git a/workflows/quickstart/executeWithArguments.js b/workflows/quickstart/executeWithArguments.js new file mode 100644 index 0000000000..624d45c360 --- /dev/null +++ b/workflows/quickstart/executeWithArguments.js @@ -0,0 +1,97 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This is a generated sample, using the typeless sample bot. Please +// look for the source TypeScript sample (.ts) for modifications. +'use strict'; + +const projectId = process.argv[2] || process.env.GOOGLE_CLOUD_PROJECT; +const location = process.argv[3] || 'us-central1'; +const workflowName = process.argv[4] || 'myFirstWorkflow'; +const searchTerm = process.argv[5] || ''; + +// [START workflows_execute_with_arguments] +const {ExecutionsClient} = require('@google-cloud/workflows'); +const client = new ExecutionsClient(); + +/** + * TODO(developer): Uncomment these variables before running the sample. + */ +// const projectId = 'my-project'; +// const location = 'us-central1'; +// const workflow = 'myFirstWorkflow'; +// const searchTerm = ''; + +/** + * Executes a Workflow and waits for the results with exponential backoff. + * @param {string} projectId The Google Cloud Project containing the workflow + * @param {string} location The workflow location + * @param {string} workflow The workflow name + * @param {string} searchTerm Optional search term to pass to the Workflow as a runtime argument + */ +async function executeWorkflow(projectId, location, workflow, searchTerm) { + /** + * Sleeps the process N number of milliseconds. + * @param {Number} ms The number of milliseconds to sleep. + */ + function sleep(ms) { + return new Promise(resolve => { + setTimeout(resolve, ms); + }); + } + const runtimeArgs = searchTerm ? {searchTerm: searchTerm} : {}; + // Execute workflow + try { + const createExecutionRes = await client.createExecution({ + parent: client.workflowPath(projectId, location, workflow), + execution: { + // Runtime arguments can be passed as a JSON string + argument: JSON.stringify(runtimeArgs), + }, + }); + const executionName = createExecutionRes[0].name; + console.log(`Created execution: ${executionName}`); + + // Wait for execution to finish, then print results. + let executionFinished = false; + let backoffDelay = 1000; // Start wait with delay of 1,000 ms + console.log('Poll every second for result...'); + while (!executionFinished) { + const [execution] = await client.getExecution({ + name: executionName, + }); + executionFinished = execution.state !== 'ACTIVE'; + + // If we haven't seen the result yet, wait a second. + if (!executionFinished) { + console.log('- Waiting for results...'); + await sleep(backoffDelay); + backoffDelay *= 2; // Double the delay to provide exponential backoff. + } else { + console.log(`Execution finished with state: ${execution.state}`); + console.log(execution.result); + return execution.result; + } + } + } catch (e) { + console.error(`Error executing workflow: ${e}`); + } +} + +executeWorkflow(projectId, location, workflowName, searchTerm).catch(err => { + console.error(err.message); + process.exitCode = 1; +}); + +// [END workflows_execute_with_arguments] diff --git a/workflows/quickstart/executeWithArguments.ts b/workflows/quickstart/executeWithArguments.ts new file mode 100644 index 0000000000..9fc1b8eba5 --- /dev/null +++ b/workflows/quickstart/executeWithArguments.ts @@ -0,0 +1,99 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +const projectId = + process.argv[2] || (process.env.GOOGLE_CLOUD_PROJECT as string); +const location = process.argv[3] || 'us-central1'; +const workflowName = process.argv[4] || 'myFirstWorkflow'; +const searchTerm = process.argv[5] || ''; + +// [START workflows_execute_with_arguments] +import {ExecutionsClient} from '@google-cloud/workflows'; +const client: ExecutionsClient = new ExecutionsClient(); +/** + * TODO(developer): Uncomment these variables before running the sample. + */ +// const projectId = 'my-project'; +// const location = 'us-central1'; +// const workflow = 'myFirstWorkflow'; +// const searchTerm = ''; + +/** + * Executes a Workflow and waits for the results with exponential backoff. + * @param {string} projectId The Google Cloud Project containing the workflow + * @param {string} location The workflow location + * @param {string} workflow The workflow name + * @param {string} searchTerm Optional search term to pass to the Workflow as a runtime argument + */ +async function executeWorkflow( + projectId: string, + location: string, + workflow: string, + searchTerm: string +) { + /** + * Sleeps the process N number of milliseconds. + * @param {Number} ms The number of milliseconds to sleep. + */ + function sleep(ms: number): Promise { + return new Promise(resolve => { + setTimeout(resolve, ms); + }); + } + const runtimeArgs = searchTerm ? {searchTerm: searchTerm} : {}; + // Execute workflow + try { + const createExecutionRes = await client.createExecution({ + parent: client.workflowPath(projectId, location, workflow), + execution: { + // Runtime arguments can be passed as a JSON string + argument: JSON.stringify(runtimeArgs), + }, + }); + const executionName = createExecutionRes[0].name; + console.log(`Created execution: ${executionName}`); + + // Wait for execution to finish, then print results. + let executionFinished = false; + let backoffDelay = 1000; // Start wait with delay of 1,000 ms + console.log('Poll every second for result...'); + while (!executionFinished) { + const [execution] = await client.getExecution({ + name: executionName, + }); + executionFinished = execution.state !== 'ACTIVE'; + + // If we haven't seen the result yet, wait a second. + if (!executionFinished) { + console.log('- Waiting for results...'); + await sleep(backoffDelay); + backoffDelay *= 2; // Double the delay to provide exponential backoff. + } else { + console.log(`Execution finished with state: ${execution.state}`); + console.log(execution.result); + return execution.result; + } + } + } catch (e) { + console.error(`Error executing workflow: ${e}`); + } +} + +executeWorkflow(projectId, location, workflowName, searchTerm).catch( + (err: Error) => { + console.error(err.message); + process.exitCode = 1; + } +); +// [END workflows_execute_with_arguments] diff --git a/workflows/quickstart/executeWithoutArguments.js b/workflows/quickstart/executeWithoutArguments.js new file mode 100644 index 0000000000..5199577418 --- /dev/null +++ b/workflows/quickstart/executeWithoutArguments.js @@ -0,0 +1,89 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This is a generated sample, using the typeless sample bot. Please +// look for the source TypeScript sample (.ts) for modifications. +'use strict'; + +const projectId = process.argv[2] || process.env.GOOGLE_CLOUD_PROJECT; +const location = process.argv[3] || 'us-central1'; +const workflowName = process.argv[4] || 'myFirstWorkflow'; + +// [START workflows_execute_without_arguments] +const {ExecutionsClient} = require('@google-cloud/workflows'); +const client = new ExecutionsClient(); + +/** + * TODO(developer): Uncomment these variables before running the sample. + */ +// const projectId = 'my-project'; +// const location = 'us-central1'; +// const workflow = 'myFirstWorkflow'; + +/** + * Executes a Workflow and waits for the results with exponential backoff. + * @param {string} projectId The Google Cloud Project containing the workflow + * @param {string} location The workflow location + * @param {string} workflow The workflow name + */ +async function executeWorkflow(projectId, location, workflow) { + /** + * Sleeps the process N number of milliseconds. + * @param {Number} ms The number of milliseconds to sleep. + */ + function sleep(ms) { + return new Promise(resolve => { + setTimeout(resolve, ms); + }); + } + // Execute workflow + try { + const createExecutionRes = await client.createExecution({ + parent: client.workflowPath(projectId, location, workflow), + }); + const executionName = createExecutionRes[0].name; + console.log(`Created execution: ${executionName}`); + + // Wait for execution to finish, then print results. + let executionFinished = false; + let backoffDelay = 1000; // Start wait with delay of 1,000 ms + console.log('Poll every second for result...'); + while (!executionFinished) { + const [execution] = await client.getExecution({ + name: executionName, + }); + executionFinished = execution.state !== 'ACTIVE'; + + // If we haven't seen the result yet, wait a second. + if (!executionFinished) { + console.log('- Waiting for results...'); + await sleep(backoffDelay); + backoffDelay *= 2; // Double the delay to provide exponential backoff. + } else { + console.log(`Execution finished with state: ${execution.state}`); + console.log(execution.result); + return execution.result; + } + } + } catch (e) { + console.error(`Error executing workflow: ${e}`); + } +} + +executeWorkflow(projectId, location, workflowName).catch(err => { + console.error(err.message); + process.exitCode = 1; +}); + +// [END workflows_execute_without_arguments] diff --git a/workflows/quickstart/executeWithoutArguments.ts b/workflows/quickstart/executeWithoutArguments.ts new file mode 100644 index 0000000000..a7d382cf46 --- /dev/null +++ b/workflows/quickstart/executeWithoutArguments.ts @@ -0,0 +1,89 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +const projectId = + process.argv[2] || (process.env.GOOGLE_CLOUD_PROJECT as string); +const location = process.argv[3] || 'us-central1'; +const workflowName = process.argv[4] || 'myFirstWorkflow'; + +// [START workflows_execute_without_arguments] +import {ExecutionsClient} from '@google-cloud/workflows'; +const client: ExecutionsClient = new ExecutionsClient(); + +/** + * TODO(developer): Uncomment these variables before running the sample. + */ +// const projectId = 'my-project'; +// const location = 'us-central1'; +// const workflow = 'myFirstWorkflow'; + +/** + * Executes a Workflow and waits for the results with exponential backoff. + * @param {string} projectId The Google Cloud Project containing the workflow + * @param {string} location The workflow location + * @param {string} workflow The workflow name + */ +async function executeWorkflow( + projectId: string, + location: string, + workflow: string +) { + /** + * Sleeps the process N number of milliseconds. + * @param {Number} ms The number of milliseconds to sleep. + */ + function sleep(ms: number): Promise { + return new Promise(resolve => { + setTimeout(resolve, ms); + }); + } + // Execute workflow + try { + const createExecutionRes = await client.createExecution({ + parent: client.workflowPath(projectId, location, workflow), + }); + const executionName = createExecutionRes[0].name; + console.log(`Created execution: ${executionName}`); + + // Wait for execution to finish, then print results. + let executionFinished = false; + let backoffDelay = 1000; // Start wait with delay of 1,000 ms + console.log('Poll every second for result...'); + while (!executionFinished) { + const [execution] = await client.getExecution({ + name: executionName, + }); + executionFinished = execution.state !== 'ACTIVE'; + + // If we haven't seen the result yet, wait a second. + if (!executionFinished) { + console.log('- Waiting for results...'); + await sleep(backoffDelay); + backoffDelay *= 2; // Double the delay to provide exponential backoff. + } else { + console.log(`Execution finished with state: ${execution.state}`); + console.log(execution.result); + return execution.result; + } + } + } catch (e) { + console.error(`Error executing workflow: ${e}`); + } +} + +executeWorkflow(projectId, location, workflowName).catch((err: Error) => { + console.error(err.message); + process.exitCode = 1; +}); +// [END workflows_execute_without_arguments] diff --git a/workflows/quickstart/package.json b/workflows/quickstart/package.json index dabe052eac..930f76907a 100644 --- a/workflows/quickstart/package.json +++ b/workflows/quickstart/package.json @@ -11,7 +11,7 @@ "build": "tsc -p .", "fix": "gts fix", "lint": "gts lint", - "test": "mocha --loader=ts-node/esm --extension ts --timeout 600000 --exit" + "test": "mocha --require ts-node/register --extension ts,js --timeout 600000 --exit" }, "dependencies": { "@google-cloud/workflows": "^3.0.0", @@ -21,6 +21,7 @@ "@types/mocha": "^10.0.1", "@types/node": "^20.0.0", "gts": "^5.0.0", - "mocha": "^10.2.0" + "mocha": "^10.2.0", + "ts-node": "^10.9.2" } } diff --git a/workflows/quickstart/test/executeWorkflow.test.js b/workflows/quickstart/test/executeWorkflow.test.js new file mode 100644 index 0000000000..f3852372de --- /dev/null +++ b/workflows/quickstart/test/executeWorkflow.test.js @@ -0,0 +1,109 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This is a generated sample, using the typeless sample bot. Please +// look for the source TypeScript sample (.ts) for modifications. +'use strict'; + +const {WorkflowsClient} = require('@google-cloud/workflows'); +const assert = require('assert'); +const cp = require('child_process'); +const {before, beforeEach, describe, it} = require('mocha'); + +const client = new WorkflowsClient(); +const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); + +const PROJECT_ID = process.env.GOOGLE_CLOUD_PROJECT; +const LOCATION_ID = 'us-central1'; +const WORKFLOW_ID = 'myFirstWorkflow'; +const SEARCH_TERM = 'cloud'; + +describe('Cloud Workflows JavaScript Execution Samples', () => { + before(async () => { + // Ensure project is configured + assert.notStrictEqual( + PROJECT_ID, + undefined, + 'GOOGLE_CLOUD_PROJECT must be set' + ); + }); + + beforeEach(async () => { + /** + * Check if the workflow exists + */ + async function workflowExists() { + try { + // Try to get the workflow + const [workflowGet] = await client.getWorkflow({ + name: client.workflowPath(PROJECT_ID, LOCATION_ID, WORKFLOW_ID), + }); + return workflowGet.state === 'ACTIVE'; + } catch (e) { + // If there is an error getting the workflow, it probably doesn't exist. + return false; + } + } + + // Create a new workflow if it doesn't exist. + if (!(await workflowExists())) { + await client.createWorkflow({ + parent: client.locationPath(PROJECT_ID, LOCATION_ID), + workflow: { + name: WORKFLOW_ID, + // Copied from: + // https://github.com/GoogleCloudPlatform/workflows-samples/blob/main/src/myFirstWorkflow.workflows.yaml + sourceContents: + '# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the "License");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an "AS IS" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# [START workflows_myfirstworkflow]\n- getCurrentTime:\n call: http.get\n args:\n url: https://timeapi.io/api/Time/current/zone?timeZone=Europe/Amsterdam\n result: currentTime\n- readWikipedia:\n call: http.get\n args:\n url: https://en.wikipedia.org/w/api.php\n query:\n action: opensearch\n search: ${currentTime.body.dayOfWeek}\n result: wikiResult\n- returnResult:\n return: ${wikiResult.body[1]}\n# [END workflows_myfirstworkflow]\n', + }, + workflowId: WORKFLOW_ID, + }); + } + }); + + after(async () => { + try { + await client.deleteWorkflow({ + name: client.workflowPath(PROJECT_ID, LOCATION_ID, WORKFLOW_ID), + }); + console.log(`The workflow with id ${WORKFLOW_ID} has been deleted.`); + } catch (err) { + console.error( + `Warning: Could not delete the workflow ${WORKFLOW_ID}:`, + err + ); + } + }); + + it('should execute the workflow using the executeWithoutArguments sample', async () => { + // Execute workflow, with long test timeout + const result = execSync( + `node --require ts-node/register ./executeWithoutArguments.js ${PROJECT_ID} ${LOCATION_ID} ${WORKFLOW_ID}` + ); + + assert.ok(result.length > 0, 'Quickstart must return non-empty result'); + }).timeout(5000); + + it('should execute the workflow using the executeWithArguments sample', async () => { + // Execute workflow, with long test timeout + const result = execSync( + `node --require ts-node/register ./executeWithArguments.js ${PROJECT_ID} ${LOCATION_ID} ${WORKFLOW_ID} ${SEARCH_TERM}` + ); + + assert.ok( + result.length > 0, + 'executeWithArguments must return non-empty result' + ); + }).timeout(5000); +}); diff --git a/workflows/quickstart/test/executeWorkflow.test.ts b/workflows/quickstart/test/executeWorkflow.test.ts new file mode 100644 index 0000000000..149f87997d --- /dev/null +++ b/workflows/quickstart/test/executeWorkflow.test.ts @@ -0,0 +1,108 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {WorkflowsClient} from '@google-cloud/workflows'; +import * as assert from 'assert'; +import * as cp from 'child_process'; +import {before, beforeEach, describe, it} from 'mocha'; + +const client: WorkflowsClient = new WorkflowsClient(); +const execSync = (cmd: string) => cp.execSync(cmd, {encoding: 'utf-8'}); + +const PROJECT_ID = process.env.GOOGLE_CLOUD_PROJECT as string; +const LOCATION_ID = 'us-central1'; +const WORKFLOW_ID = 'myFirstWorkflow'; +const SEARCH_TERM = 'cloud'; + +describe('Cloud Workflows TypeScript Execution Samples', () => { + before(async () => { + // Ensure project is configured + assert.notStrictEqual( + PROJECT_ID, + undefined, + 'GOOGLE_CLOUD_PROJECT must be set' + ); + }); + + beforeEach(async () => { + /** + * Check if the workflow exists + */ + async function workflowExists() { + try { + // Try to get the workflow + const [workflowGet] = await client.getWorkflow({ + name: client.workflowPath(PROJECT_ID, LOCATION_ID, WORKFLOW_ID), + }); + return workflowGet.state === 'ACTIVE'; + } catch { + // If there is an error getting the workflow, it probably doesn't exist. + return false; + } + } + + // Create a new workflow if it doesn't exist. + if (!(await workflowExists())) { + await client.createWorkflow({ + parent: client.locationPath(PROJECT_ID, LOCATION_ID), + workflow: { + name: WORKFLOW_ID, + // Copied from: + // https://github.com/GoogleCloudPlatform/workflows-samples/blob/main/src/myFirstWorkflow.workflows.yaml + sourceContents: + '# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the "License");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an "AS IS" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n- getCurrentTime:\n call: http.get\n args:\n url: https://timeapi.io/api/Time/current/zone?timeZone=Europe/Amsterdam\n result: currentTime\n- readWikipedia:\n call: http.get\n args:\n url: https://en.wikipedia.org/w/api.php\n query:\n action: opensearch\n search: ${currentTime.body.dayOfWeek}\n result: wikiResult\n- returnResult:\n return: ${wikiResult.body[1]}\n', + }, + workflowId: WORKFLOW_ID, + }); + } + }); + + after(async () => { + try { + await client.deleteWorkflow({ + name: client.workflowPath(PROJECT_ID, LOCATION_ID, WORKFLOW_ID), + }); + console.log(`The workflow with id ${WORKFLOW_ID} has been deleted.`); + } catch (err) { + console.error( + `Warning: Could not delete the workflow ${WORKFLOW_ID}:`, + err + ); + } + }); + + it('should execute the workflow using the executeWithoutArguments sample', async () => { + // Execute workflow, with long test timeout + const result = execSync( + `node --require ts-node/register ./executeWithoutArguments.ts ${PROJECT_ID} ${LOCATION_ID} ${WORKFLOW_ID}` + ); + + assert.ok( + result.length > 0, + 'executeWithoutArguments must return non-empty result' + ); + }).timeout(5000); + + it('should execute the workflow using the executeWithArguments sample', async () => { + // Execute workflow, with long test timeout + const result = execSync( + `node --require ts-node/register ./executeWithArguments.ts ${PROJECT_ID} ${LOCATION_ID} ${WORKFLOW_ID} ${SEARCH_TERM}` + ); + + assert.ok( + result.length > 0, + 'executeWithArguments must return non-empty result' + ); + }).timeout(5000); +}); diff --git a/workflows/quickstart/test/quickstart.test.js b/workflows/quickstart/test/quickstart.test.js index 954d1f920e..8770f16496 100644 --- a/workflows/quickstart/test/quickstart.test.js +++ b/workflows/quickstart/test/quickstart.test.js @@ -28,7 +28,7 @@ const PROJECT_ID = process.env.GOOGLE_CLOUD_PROJECT; const LOCATION_ID = 'us-central1'; const WORKFLOW_ID = 'myFirstWorkflow'; -describe('Cloud Workflows Quickstart Tests', () => { +describe('Cloud Workflows JavaScript Quickstart Tests', () => { before(async () => { // Ensure project is configured assert.notStrictEqual( @@ -71,16 +71,26 @@ describe('Cloud Workflows Quickstart Tests', () => { } }); + after(async () => { + try { + await client.deleteWorkflow({ + name: client.workflowPath(PROJECT_ID, LOCATION_ID, WORKFLOW_ID), + }); + console.log(`The workflow with id ${WORKFLOW_ID} has been deleted.`); + } catch (err) { + console.error( + `Warning: Could not delete the workflow ${WORKFLOW_ID}:`, + err + ); + } + }); + it('should execute the quickstart', async () => { // Execute workflow, with long test timeout const result = execSync( - `node --loader ts-node/esm ./index.ts ${PROJECT_ID} ${LOCATION_ID} ${WORKFLOW_ID}` + `node --require ts-node/register ./index.js ${PROJECT_ID} ${LOCATION_ID} ${WORKFLOW_ID}` ); - assert.strictEqual( - result.length > 0, - true, - 'Quickstart must return non-empty result' - ); + assert.ok(result.length > 0, 'Quickstart must return non-empty result'); }).timeout(5000); }); diff --git a/workflows/quickstart/test/quickstart.test.ts b/workflows/quickstart/test/quickstart.test.ts index aa51b2ab3a..590c1852c4 100644 --- a/workflows/quickstart/test/quickstart.test.ts +++ b/workflows/quickstart/test/quickstart.test.ts @@ -25,7 +25,7 @@ const LOCATION_ID = 'us-central1'; const WORKFLOW_ID = 'myFirstWorkflow'; const SEARCH_TERM = 'cloud'; -describe('Cloud Workflows Quickstart Tests', () => { +describe('Cloud Workflows TypeScript Quickstart Tests', () => { before(async () => { // Ensure project is configured assert.notStrictEqual( @@ -68,29 +68,35 @@ describe('Cloud Workflows Quickstart Tests', () => { } }); + after(async () => { + try { + await client.deleteWorkflow({ + name: client.workflowPath(PROJECT_ID, LOCATION_ID, WORKFLOW_ID), + }); + console.log(`The workflow with id ${WORKFLOW_ID} has been deleted.`); + } catch (err) { + console.error( + `Warning: Could not delete the workflow ${WORKFLOW_ID}:`, + err + ); + } + }); + it('should execute the quickstart without optional search term', async () => { // Execute workflow, with long test timeout const result = execSync( - `node --loader ts-node/esm ./index.ts ${PROJECT_ID} ${LOCATION_ID} ${WORKFLOW_ID}` + `node --require ts-node/register ./index.ts ${PROJECT_ID} ${LOCATION_ID} ${WORKFLOW_ID}` ); - assert.strictEqual( - result.length > 0, - true, - 'Quickstart must return non-empty result' - ); + assert.ok(result.length > 0, 'Quickstart must return non-empty result'); }).timeout(5000); it('should execute the quickstart with optional search term', async () => { // Execute workflow, with long test timeout const result = execSync( - `node --loader ts-node/esm ./index.ts ${PROJECT_ID} ${LOCATION_ID} ${WORKFLOW_ID} ${SEARCH_TERM}` + `node --require ts-node/register ./index.ts ${PROJECT_ID} ${LOCATION_ID} ${WORKFLOW_ID} ${SEARCH_TERM}` ); - assert.strictEqual( - result.length > 0, - true, - 'Quickstart must return non-empty result' - ); + assert.ok(result.length > 0, 'Quickstart must return non-empty result'); }).timeout(5000); }); diff --git a/workflows/quickstart/tsconfig.json b/workflows/quickstart/tsconfig.json index 121cda905f..d4868c5876 100644 --- a/workflows/quickstart/tsconfig.json +++ b/workflows/quickstart/tsconfig.json @@ -4,7 +4,7 @@ "strict": true, "noImplicitAny": false, "esModuleInterop": true, - "moduleResolution": "node", - "module": "commonjs" + "moduleResolution": "node16", + "module": "node16" } } From f4616018b41a0e941b02d735f716a302ef1ec184 Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Thu, 23 Apr 2026 23:19:51 +0000 Subject: [PATCH 2/2] test: increase timeout for workflow execution tests Increased the timeout to account for the latency of workflow execution and polling. --- workflows/quickstart/test/executeWorkflow.test.js | 9 ++++++--- workflows/quickstart/test/executeWorkflow.test.ts | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/workflows/quickstart/test/executeWorkflow.test.js b/workflows/quickstart/test/executeWorkflow.test.js index f3852372de..8c78e05560 100644 --- a/workflows/quickstart/test/executeWorkflow.test.js +++ b/workflows/quickstart/test/executeWorkflow.test.js @@ -92,8 +92,11 @@ describe('Cloud Workflows JavaScript Execution Samples', () => { `node --require ts-node/register ./executeWithoutArguments.js ${PROJECT_ID} ${LOCATION_ID} ${WORKFLOW_ID}` ); - assert.ok(result.length > 0, 'Quickstart must return non-empty result'); - }).timeout(5000); + assert.ok( + result.length > 0, + 'executeWithoutArguments must return non-empty result' + ); + }).timeout(60000); it('should execute the workflow using the executeWithArguments sample', async () => { // Execute workflow, with long test timeout @@ -105,5 +108,5 @@ describe('Cloud Workflows JavaScript Execution Samples', () => { result.length > 0, 'executeWithArguments must return non-empty result' ); - }).timeout(5000); + }).timeout(60000); }); diff --git a/workflows/quickstart/test/executeWorkflow.test.ts b/workflows/quickstart/test/executeWorkflow.test.ts index 149f87997d..b22dcb0a7e 100644 --- a/workflows/quickstart/test/executeWorkflow.test.ts +++ b/workflows/quickstart/test/executeWorkflow.test.ts @@ -92,7 +92,7 @@ describe('Cloud Workflows TypeScript Execution Samples', () => { result.length > 0, 'executeWithoutArguments must return non-empty result' ); - }).timeout(5000); + }).timeout(60000); it('should execute the workflow using the executeWithArguments sample', async () => { // Execute workflow, with long test timeout @@ -104,5 +104,5 @@ describe('Cloud Workflows TypeScript Execution Samples', () => { result.length > 0, 'executeWithArguments must return non-empty result' ); - }).timeout(5000); + }).timeout(60000); });