You can run yarn dev:apify to run the CLI in development mode. This will use the local version of the CLI instead of the one installed globally.
Tests are implemented using the Vitest framework. You need to have Apify account to test all apify-cli features.
Then you can run tests with commands in repository root directory:
-
Install all dependencies:
yarn -
Run tests using credentials of the 'apify-test' user:
TEST_USER_TOKEN=<apifyUserApiToken> yarn test:all
Only users with access to apify-cli package can publish new version.
Release of new versions is managed by GitHub Actions. On pushes to the master branch, prerelease versions are automatically produced. Latest releases are triggered manually through the GitHub release tool. After creating a release there, Actions will automatically produce the latest version of the package.
-
Manually increment version in
package.json -
GitHub Actions build is triggered by a push to
master(typically a merge of a PR). -
To trigger the latest release, go to the GitHub release tool (select
releasesunder<> Code). There, draft a new release, fill the form and hitPublish release. Actions will automatically release the latest version of the package.
In test/__setup__/hooks we have a collection of hooks that you can use while writing tests to set up the testing environment to be usable when running tests in parallel (especially useful for tests that require authenticating into an Apify account).
Use this hook at the start of your test file to mark the entire suite as require-ing a separated authentication setup. By default, this will recreate the authentication setup per test in your suite, but you can disable that by passing in { perTest: false } in the call to useAuthSetup.`
If you're writing a test case or file that relies on API interactions, make sure it either goes in the test/api folder, and that it has a [api] reference in the name of the test case (usually at the start).
If your test file also mixes local tests, always add [api] for test cases that need the API. They will automatically be skipped for local tests.
import { useAuthSetup } from "./__setup__/hooks";
useAuthSetup();
// Alternatively, if this suite requires the authentication to persist across all tests
useAuthSetup({ perTest: false });This hook should always be used when working with commands that alter the file system. This hook:
- creates your temporary directory with the name you provided
- provides calls for before and after all tests to setup and clean up the temporary directory
- supports mocking the process cwd to the temporary directory so you can run commands and test their behavior.
Important note about the cwd mocking: when you use this hook and tell it to mock the cwd, you need to ensure these following things always happen:
- You import
processfromnode:processin your command or file you want to test with the mocked cwd. You do not useglobalThis.processat all! - You import the files that may rely on the mocked cwd AFTER you call
useTempPathin your test file, by usingawait import()instead ofimport x from '..';
It also comes with several options:
create: defaulted totrue, it decides if the temporary directory should be created or not in the beforeAll hook.remove: defaulted totrue, it decides if the temporary directory should be removed or not in the afterAll hook.cwd: defaulted tofalse, it decides if the process.cwd should be mocked to the temporary directory or not.cwdParent: defaulted tofalse, it decides whether the initial value of the mocked process.cwd will point to the parent directory of the temporary directory or the actual temporary directory.
This hook also returns several values in an object:
tmpPath: the full path to the temporary directory that was requestedjoinPath: a utility function similar topath.jointhat lets you work with paths in the temporary directorybeforeAllCalls: a function you should manually call in yourbeforeAllhook to set up the temporary directory as well as the used cwd mockafterAllCalls: a function you should manually call in yourafterAllhook to clean up the temporary directorytoggleCwdBetweenFullAndParentPath: a function you can call to toggle the cwd mock between the full path to the temporary directory and the parent directory of the temporary directory
This example assumes you've also handled logging in.
import { useTempPath } from "./__setup__/hooks";
import { writeFile } from "node:fs/promises";
const ACTOR_NAME = "owo";
const {
beforeAllCalls,
afterAllCalls,
joinPath,
toggleCwdBetweenFullAndParentPath,
} = useTempPath(ACTOR_NAME, {
cwd: true,
cwdParent: true,
create: true,
remove: true,
});
const { CreateCommand } = await import("../../src/commands/create.js");
const { PushCommand } = await import("../../src/commands/push.js");
const { CallCommand } = await import("../../src/commands/call.js");
beforeAll(async () => {
await beforeAllCalls();
await CreateCommand.run(
[ACTOR_NAME, "--template", "project_empty", "--skip-dependency-install"],
import.meta.url,
);
const code = `
import { Actor } from 'apify';
Actor.main(async () => {
await Actor.setValue('OUTPUT', 'Hello world!');
console.log('Done!');
});`;
await writeFile(joinPath("main.js"), code);
toggleCwdBetweenFullAndParentPath();
await PushCommand.run(["--no-prompt"], import.meta.url);
});
afterAll(async () => {
await afterAllCalls();
});Running commands in tests can be done by calling testRunCommand (imported from the command framework)