Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion docs/man_pages/project/testing/dev-test-android.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Run tests on a selected device | `$ ns test android --device <Device ID> [--watc
Runs the tests in your project on connected Android devices and running native emulators.<% if(isConsole) { %> Your project must already be configured for unit testing by running `$ ns test init`.<% } %>

### Options
* `--watch` - If set, when you save changes to the project, changes are automatically synchronized to the connected device and tests are re-run.
* `--watch` - Enabled by default; when you save changes to the project, changes are automatically synchronized to the connected device and tests are re-run. Pass `--no-watch` to run the tests once. In CI environments (when the `CI` environment variable is set), it defaults to disabled.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
* `--device` - Specifies the serial number or the index of the connected device on which to run the tests. To list all connected devices, grouped by platform, run `$ ns device`
* `--debug-brk` - Runs the tests under the debugger. The debugger will break just before your tests are executed, so you have a chance to place breakpoints.

Expand Down
2 changes: 1 addition & 1 deletion docs/man_pages/project/testing/dev-test-ios.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Runs the tests in your project on connected iOS devices or the iOS Simulator.<%

<% if((isConsole && isMacOS) || isHtml) { %>
### Options
* `--watch` - If set, when you save changes to the project, changes are automatically synchronized to the connected device and tests are re-ran.
* `--watch` - Enabled by default; when you save changes to the project, changes are automatically synchronized to the connected device and tests are re-ran. Pass `--no-watch` to run the tests once. In CI environments (when the `CI` environment variable is set), it defaults to disabled.
* `--device` - Specifies the serial number or the index of the connected device on which you want to run tests. To list all connected devices, grouped by platform, run `$ ns device`. You cannot set `--device` and `--emulator` simultaneously.
* `--emulator` - Runs tests on the iOS Simulator. You cannot set `--device` and `--emulator` simultaneously.
* `--debug-brk` - Runs the tests under the debugger. The debugger will break just before your tests are executed, so you have a chance to place breakpoints.
Expand Down
2 changes: 1 addition & 1 deletion docs/man_pages/project/testing/test-android.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Run tests on a selected device | `$ ns test android --device <Device ID> [--watc

### Options

* `--watch` - If set, when you save changes to the project, changes are automatically synchronized to the connected device and tests are re-run.
* `--watch` - Enabled by default; when you save changes to the project, changes are automatically synchronized to the connected device and tests are re-run. Pass `--no-watch` to run the tests once. In CI environments (when the `CI` environment variable is set), it defaults to disabled.
* `--device` - Specifies the serial number or the index of the connected device on which to run the tests. To list all connected devices, grouped by platform, run `$ ns device`. `<Device ID>` is the device index or identifier as listed by the `$ ns device` command.
* `--debug-brk` - Runs the tests under the debugger. The debugger will break just before your tests are executed, so you have a chance to place breakpoints.
* `--env.*` - Specifies additional flags that the bundler may process. Can be passed multiple times. Supported additional flags:
Expand Down
2 changes: 1 addition & 1 deletion docs/man_pages/project/testing/test-ios.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Run tests in the iOS Simulator | `$ ns test ios --emulator [--watch] [--debug-br

### Options

* `--watch` - If set, when you save changes to the project, changes are automatically synchronized to the connected device and tests are re-ran.
* `--watch` - Enabled by default; when you save changes to the project, changes are automatically synchronized to the connected device and tests are re-ran. Pass `--no-watch` to run the tests once. In CI environments (when the `CI` environment variable is set), it defaults to disabled.
* `--device` - Specifies the serial number or the index of the connected device on which you want to run tests. To list all connected devices, grouped by platform, run `$ ns device`. You cannot set `--device` and `--emulator` simultaneously. `<Device ID>` is the device index or identifier as listed by the `$ ns device` command.
* `--emulator` - Runs tests on the iOS Simulator. You cannot set `--device` and `--emulator` simultaneously.
* `--debug-brk` - Runs the tests under the debugger. The debugger will break just before your tests are executed, so you have a chance to place breakpoints.
Expand Down
11 changes: 9 additions & 2 deletions lib/commands/test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { hasValidAndroidSigning } from "../common/helpers";
import { hasValidAndroidSigning, isCIEnvironment } from "../common/helpers";
import {
ANDROID_RELEASE_BUILD_ERROR_MESSAGE,
ANDROID_APP_BUNDLE_SIGNING_ERROR_MESSAGE,
Expand All @@ -25,6 +25,13 @@ abstract class TestCommandBase {
public allowedParameters: ICommandParameter[] = [];
public dashedOptions = {
hmr: { type: OptionType.Boolean, default: false, hasSensitiveValue: false },
// Watch mode keeps the run alive waiting for changes; CI runs must
// execute once and exit, so --watch defaults to off there.
watch: {
type: OptionType.Boolean,
default: !isCIEnvironment(),
hasSensitiveValue: false,
},
};

protected abstract platform: string;
Expand Down Expand Up @@ -214,7 +221,7 @@ class TestAndroidCommand extends TestCommandBase implements ICommand {
}
}

class TestIosCommand extends TestCommandBase implements ICommand {
export class TestIosCommand extends TestCommandBase implements ICommand {
protected platform = "iOS";

constructor(
Expand Down
2 changes: 1 addition & 1 deletion lib/common/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ function isRunningInTTY(): boolean {
);
}

function isCIEnvironment(): boolean {
export function isCIEnvironment(): boolean {
// The following CI environments set their own environment variables that we respect:
// travis: "CI",
// circleCI: "CI",
Expand Down
120 changes: 120 additions & 0 deletions test/commands/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { Yok } from "../../lib/common/yok";
import { assert } from "chai";
import { Options } from "../../lib/options";
import { TestIosCommand } from "../../lib/commands/test";
import { IOptions } from "../../lib/declarations";
import { ICommand } from "../../lib/common/definitions/commands";
import { IInjector } from "../../lib/common/definitions/yok";
import { IConfigurationSettings } from "../../lib/common/declarations";

const CI_ENVIRONMENT_VARIABLES = ["CI", "JENKINS_HOME"];

function createTestInjector(): IInjector {
const testInjector = new Yok();
testInjector.register("settingsService", {
setSettings: (settings: IConfigurationSettings): any => undefined,
getProfileDir: () => "profileDir",
});
testInjector.register("errors", {
fail: (message: string): never => {
throw new Error(message);
},
failWithHelp: (message: string): never => {
throw new Error(message);
},
});
testInjector.register("logger", {
warn: (message: string): void => undefined,
});

testInjector.register("projectData", {});
testInjector.register("testExecutionService", {});
testInjector.register("vitestExecutionService", {});
testInjector.register("analyticsService", {});
testInjector.register("platformEnvironmentRequirements", {});
testInjector.register("cleanupService", {});
testInjector.register("liveSyncCommandHelper", {});
testInjector.register("devicesService", {});
testInjector.register("migrateController", {});

return testInjector;
}

interface IResolvedTestCommand {
command: ICommand;
options: IOptions;
}

function resolveTestIosCommand(): IResolvedTestCommand {
const testInjector = createTestInjector();
const options = testInjector.resolve(Options);
testInjector.register("options", options);
testInjector.registerCommand("test|ios", TestIosCommand);
const command = testInjector.resolveCommand("test|ios");
return { command, options };
}

function validateWithArgs(
resolved: IResolvedTestCommand,
args: string[] = [],
): void {
args.forEach((arg) => process.argv.push(arg));
resolved.options.validateOptions(resolved.command.dashedOptions);
args.forEach(() => process.argv.pop());
}

describe("test ios command", () => {
const savedCiEnvironment: { [key: string]: string } = {};

beforeEach(() => {
CI_ENVIRONMENT_VARIABLES.forEach((name) => {
savedCiEnvironment[name] = process.env[name];
delete process.env[name];
});
});

afterEach(() => {
CI_ENVIRONMENT_VARIABLES.forEach((name) => {
if (savedCiEnvironment[name] === undefined) {
delete process.env[name];
} else {
process.env[name] = savedCiEnvironment[name];
}
});
});

describe("--watch option", () => {
it("defaults to off in CI environments", () => {
process.env.CI = "true";
const resolved = resolveTestIosCommand();
validateWithArgs(resolved);
assert.isFalse(resolved.options.argv.watch);
});

it("defaults to off when JENKINS_HOME is set", () => {
process.env.JENKINS_HOME = "/var/jenkins";
const resolved = resolveTestIosCommand();
validateWithArgs(resolved);
assert.isFalse(resolved.options.argv.watch);
});

it("defaults to on outside CI environments", () => {
const resolved = resolveTestIosCommand();
validateWithArgs(resolved);
assert.isTrue(resolved.options.argv.watch);
});

it("stays on when --watch is passed explicitly in CI", () => {
process.env.CI = "true";
const resolved = resolveTestIosCommand();
validateWithArgs(resolved, ["--watch"]);
assert.isTrue(resolved.options.argv.watch);
});

it("stays off when --no-watch is passed outside CI", () => {
const resolved = resolveTestIosCommand();
validateWithArgs(resolved, ["--no-watch"]);
assert.isFalse(resolved.options.argv.watch);
});
});
});