Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
"@oclif/core": "^4",
"@oclif/multi-stage-output": "^0.8.29",
"@salesforce/agents": "^0.20.0",
"@salesforce/core": "^8.23.7",
"@salesforce/core": "^8.24.0",
"@salesforce/kit": "^3.2.3",
"@salesforce/sf-plugins-core": "^12.2.6",
"@salesforce/source-deploy-retrieve": "^12.31.2",
"@salesforce/source-deploy-retrieve": "^12.31.6",
"@salesforce/types": "^1.5.0",
"ansis": "^3.3.2",
"fast-xml-parser": "^4.5.1",
Expand Down
3 changes: 2 additions & 1 deletion test/nuts/agent.activate.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ describe('agent activate/deactivate NUTs', function () {
return lastBotVersion.Status;
};

before(async () => {
before(async function () {
this.timeout(30 * 60 * 1000); // 30 minutes for setup
await getTestSession();
username = getUsername();
defaultOrg = await Org.create({ aliasOrUsername: username });
Expand Down
8 changes: 6 additions & 2 deletions test/nuts/agent.create.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,16 @@ import { getTestSession, getUsername } from './shared-setup.js';

/* eslint-disable no-console */

describe('agent create', () => {
describe('agent create', function () {
// Increase timeout for setup since shared setup includes long waits and deployments
this.timeout(30 * 60 * 1000); // 30 minutes

let session: TestSession;
let username: string;
const specFileName = genUniqueString('agentSpec_%s.yaml');

before(async () => {
before(async function () {
this.timeout(30 * 60 * 1000); // 30 minutes for setup
session = await getTestSession();
username = getUsername();
});
Expand Down
8 changes: 6 additions & 2 deletions test/nuts/agent.generate.authoring-bundle.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ import { getTestSession, getUsername } from './shared-setup.js';

let session: TestSession;

describe('agent generate authoring-bundle NUTs', () => {
before(async () => {
describe('agent generate authoring-bundle NUTs', function () {
// Increase timeout for setup since shared setup includes long waits and deployments
this.timeout(30 * 60 * 1000); // 30 minutes

before(async function () {
this.timeout(30 * 60 * 1000); // 30 minutes for setup
session = await getTestSession();
});

Expand Down
8 changes: 6 additions & 2 deletions test/nuts/agent.generate.template.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,13 @@ import { execCmd } from '@salesforce/cli-plugins-testkit';
import type { AgentGenerateTemplateResult } from '../../src/commands/agent/generate/template.js';
import { getTestSession } from './shared-setup.js';

describe('agent generate template NUTs', () => {
describe('agent generate template NUTs', function () {
// Increase timeout for setup since shared setup includes long waits and deployments
this.timeout(30 * 60 * 1000); // 30 minutes

let session: TestSession;
before(async () => {
before(async function () {
this.timeout(30 * 60 * 1000); // 30 minutes for setup
session = await getTestSession();
});

Expand Down
8 changes: 6 additions & 2 deletions test/nuts/agent.generate.test-spec.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,13 @@ import { genUniqueString, TestSession } from '@salesforce/cli-plugins-testkit';
import { execCmd } from '@salesforce/cli-plugins-testkit';
import { getTestSession } from './shared-setup.js';

describe('agent generate test-spec NUTs', () => {
describe('agent generate test-spec NUTs', function () {
// Increase timeout for setup since shared setup includes long waits and deployments
this.timeout(30 * 60 * 1000); // 30 minutes

let session: TestSession;
before(async () => {
before(async function () {
this.timeout(30 * 60 * 1000); // 30 minutes for setup
session = await getTestSession();
});

Expand Down
8 changes: 6 additions & 2 deletions test/nuts/agent.test.create.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,13 @@ import { execCmd } from '@salesforce/cli-plugins-testkit';
import type { AgentTestCreateResult } from '../../src/commands/agent/test/create.js';
import { getTestSession, getUsername } from './shared-setup.js';

describe('agent test create', () => {
describe('agent test create', function () {
// Increase timeout for setup since shared setup includes long waits and deployments
this.timeout(30 * 60 * 1000); // 30 minutes

let session: TestSession;
before(async () => {
before(async function () {
this.timeout(30 * 60 * 1000); // 30 minutes for setup
session = await getTestSession();
});
// this NUT is failing on windows due to an invalid api name, but it seems valid to me, passes on unix
Expand Down
8 changes: 6 additions & 2 deletions test/nuts/agent.test.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@ import { getTestSession, getUsername } from './shared-setup.js';

/* eslint-disable no-console */

describe('agent test', () => {
describe('agent test', function () {
// Increase timeout for setup since shared setup includes long waits and deployments
this.timeout(30 * 60 * 1000); // 30 minutes

const agentTestName = 'Local_Info_Agent_Test';

before(async () => {
before(async function () {
this.timeout(30 * 60 * 1000); // 30 minutes for setup
await getTestSession();
});

Expand Down
87 changes: 82 additions & 5 deletions test/nuts/shared-setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@

import { join } from 'node:path';
import { Duration, TestSession } from '@salesforce/cli-plugins-testkit';
import { ComponentSetBuilder } from '@salesforce/source-deploy-retrieve';
import { Org, SfError, User } from '@salesforce/core';
import { sleep } from '@salesforce/kit';
import { ComponentSetBuilder, RequestStatus, type ScopedPostDeploy } from '@salesforce/source-deploy-retrieve';
import { Org, SfError, User, Lifecycle } from '@salesforce/core';
import { sleep, ensureArray } from '@salesforce/kit';

/* eslint-disable no-console */

Expand Down Expand Up @@ -131,6 +131,74 @@ export async function getTestSession(): Promise<TestSession> {

// Set environment variable for string replacement
process.env.AGENT_USER_USERNAME = agentUsername;
process.env.SF_AAB_COMPILATION = 'false';

// Set up deploy event listeners to log progress
const lifecycle = Lifecycle.getInstance();
let lastDeployed = 0;
let lastTotal = 0;

lifecycle.on('scopedPreDeploy', () => {
console.log('[DEPLOY] Starting deployment...');
// Reset progress tracking for new deployment
lastDeployed = 0;
lastTotal = 0;
return Promise.resolve();
});

lifecycle.on('scopedPostDeploy', (result: ScopedPostDeploy) => {
const deployResult = result.deployResult.response;
const status = deployResult.status;
const numberComponentErrors = deployResult.numberComponentErrors ?? 0;
const numberComponentsDeployed = deployResult.numberComponentsDeployed ?? 0;
const numberComponentsTotal = deployResult.numberComponentsTotal ?? 0;
const numberTestErrors = deployResult.numberTestErrors ?? 0;
const numberTestsCompleted = deployResult.numberTestsCompleted ?? 0;
const numberTestsTotal = deployResult.numberTestsTotal ?? 0;

// Log progress during polling (only if changed)
if (
(numberComponentsDeployed !== lastDeployed || numberComponentsTotal !== lastTotal) &&
numberComponentsTotal > 0
) {
console.log(
`[DEPLOY] Progress: ${numberComponentsDeployed}/${numberComponentsTotal} components deployed${
numberComponentErrors > 0 ? `, ${numberComponentErrors} errors` : ''
}`
);
lastDeployed = numberComponentsDeployed;
lastTotal = numberComponentsTotal;
}

// Log final status when deployment is complete
const isComplete =
status === RequestStatus.Succeeded ||
status === RequestStatus.Failed ||
status === RequestStatus.Canceled;
if (isComplete) {
console.log(`[DEPLOY] Deployment completed - Status: ${status}`);
console.log(
`[DEPLOY] Components: ${numberComponentsDeployed}/${numberComponentsTotal} deployed, ${numberComponentErrors} errors`
);
if (numberTestsTotal > 0) {
console.log(
`[DEPLOY] Tests: ${numberTestsCompleted}/${numberTestsTotal} completed, ${numberTestErrors} errors`
);
}
const componentFailures = ensureArray(deployResult.details?.componentFailures);
if (componentFailures.length > 0) {
console.log(`[DEPLOY] Component failures: ${componentFailures.length}`);
componentFailures.slice(0, 5).forEach((failure, idx) => {
console.log(
`[DEPLOY] Failure ${idx + 1}: ${failure.fullName ?? 'unknown'} - ${
failure.problemType ?? 'unknown'
}: ${failure.problem ?? 'unknown'}`
);
});
}
}
return Promise.resolve();
});

console.log('deploying metadata (no AiEvaluationDefinition)');

Expand All @@ -141,7 +209,13 @@ export async function getTestSession(): Promise<TestSession> {
},
});
const deploy1 = await cs1.deploy({ usernameOrConnection: defaultOrg.username });
await deploy1.pollStatus({ frequency: Duration.seconds(10) });
// pollStatus waits until deployment completes - will throw if deployment fails
await deploy1.pollStatus({ frequency: Duration.seconds(10), timeout: Duration.minutes(30) });
console.log('[DEPLOY] First deployment completed successfully');

// Reset for second deployment
lastDeployed = 0;
lastTotal = 0;

console.log('deploying metadata (AiEvaluationDefinition)');

Expand All @@ -152,7 +226,10 @@ export async function getTestSession(): Promise<TestSession> {
},
});
const deploy2 = await cs2.deploy({ usernameOrConnection: defaultOrg.username });
await deploy2.pollStatus({ frequency: Duration.seconds(10) });
// pollStatus waits until deployment completes - will throw if deployment fails
await deploy2.pollStatus({ frequency: Duration.seconds(10), timeout: Duration.minutes(30) });
console.log('[DEPLOY] Second deployment completed successfully');
console.log('[DEPLOY] All deployments complete, tests can now run');
}
}

Expand Down
8 changes: 6 additions & 2 deletions test/nuts/template.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,14 @@ import {
} from '../../src/commands/agent/generate/template.js';
import { getTestSession } from './shared-setup.js';

describe('agent generate template NUTs', () => {
describe('agent generate template NUTs', function () {
// Increase timeout for setup since shared setup includes long waits and deployments
this.timeout(30 * 60 * 1000); // 30 minutes

let session: TestSession;

before(async () => {
before(async function () {
this.timeout(30 * 60 * 1000); // 30 minutes for setup
session = await getTestSession();
});

Expand Down
7 changes: 4 additions & 3 deletions test/nuts/z1.agent.validate.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ import type { AgentValidateAuthoringBundleResult } from '../../src/commands/agen
import { getTestSession, getUsername } from './shared-setup.js';

describe('agent validate authoring-bundle NUTs', function () {
// Increase timeout for setup since shared setup includes a long wait on Windows
this.timeout(15 * 60 * 1000); // 15 minutes
// Increase timeout for setup since shared setup includes long waits and deployments
this.timeout(30 * 60 * 1000); // 30 minutes

before(async () => {
before(async function () {
this.timeout(30 * 60 * 1000); // 30 minutes for setup
await getTestSession();
});

Expand Down
7 changes: 4 additions & 3 deletions test/nuts/z2.agent.publish.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ import type { AgentGenerateAuthoringBundleResult } from '../../src/commands/agen
import { getAgentUsername, getTestSession, getUsername } from './shared-setup.js';

describe('agent publish authoring-bundle NUTs', function () {
// Increase timeout for setup since shared setup includes a long wait on Windows
this.timeout(15 * 60 * 1000); // 15 minutes
// Increase timeout for setup since shared setup includes long waits and deployments
this.timeout(30 * 60 * 1000); // 30 minutes

let session: TestSession;
const bundleApiName = genUniqueString('Test_Agent_%s');
before(async () => {
before(async function () {
this.timeout(30 * 60 * 1000); // 30 minutes for setup
session = await getTestSession();
});

Expand Down
Loading