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
24 changes: 19 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,21 +50,35 @@ The config file - which unless specified in the cli should live in `./owl.config

### Building the app

##### Options
#### Options

| Name | Required | Default | Choices | Description |
| ---------- | -------- | ----------------- | --------------- | --------------------------------------- |
| `config` | false | ./owl.config.json | - | Path to the configuration file |
| `platform` | true | - | `ios`,`android` | The platform the app should be built on |
| Name | Required | Default | Options/Types | Description |
| ---------------- | -------- | ----------------- | --------------- | --------------------------------------- |
| `config`, `-c` | false | ./owl.config.json | String | Path to the configuration file |
| `platform`, `-p` | true | - | `ios`,`android` | The platform the app should be built on |

#### Examples

```
owl build --platform ios --config ./owl.config.json
```

### Running the tests

#### Options

| Name | Required | Default | Options/Types | Description |
| ---------------- | -------- | ----------------- | --------------- | ----------------------------------------------- |
| `config`, `-c` | false | ./owl.config.json | String | Path to the configuration file |
| `platform`, `-p` | true | - | `ios`,`android` | The platform the app should be built on |
| `update`, `-u` | true | false | Boolean | A flag about rewriting existing baseline images |

#### Examples

```
owl test --platform ios
owl test --platform ios --config ./owl.config.json
owl test --platform ios --update
```

[github-image]: https://github.com/FormidableLabs/react-native-owl/workflows/Run%20Tests/badge.svg
Expand Down
4 changes: 2 additions & 2 deletions src/cli/build.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import path from 'path';
import execa from 'execa';

import { buildAndroid, buildHandler, buildIOS } from './build';
import { BuildRunOptions, Config } from './types';
import { CliBuildOptions, Config } from './types';
import { Logger } from '../logger';
import * as configHelpers from './config';

Expand Down Expand Up @@ -128,7 +128,7 @@ describe('build.ts', () => {
const args = {
platform: 'ios',
config: './owl.config.json',
} as BuildRunOptions;
} as CliBuildOptions;

const config: Config = {
ios: {
Expand Down
4 changes: 2 additions & 2 deletions src/cli/build.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import path from 'path';
import execa from 'execa';

import { BuildRunOptions, Config } from './types';
import { CliBuildOptions, Config } from './types';
import { Logger } from '../logger';
import { getConfig } from './config';

Expand Down Expand Up @@ -46,7 +46,7 @@ export const buildAndroid = async (
await execa.command(buildCommand.join(' '), { stdio: 'inherit', cwd });
};

export const buildHandler = async (args: BuildRunOptions) => {
export const buildHandler = async (args: CliBuildOptions) => {
const config = await getConfig(args.config);
const logger = new Logger(config.debug);
const buildProject = args.platform === 'ios' ? buildIOS : buildAndroid;
Expand Down
19 changes: 16 additions & 3 deletions src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,36 @@ const configOption: Options = {
default: './owl.config.json',
};

const builderOptions = {
const updateOption: Options = {
alias: 'u',
describe: 'Update the baseline screenshots',
type: 'boolean',
default: false,
};

const builderOptionsRun = {
config: configOption,
platform: plaformOption,
};

const builderOptionsTest = {
config: configOption,
platform: plaformOption,
update: updateOption,
};

argv
.usage('Usage: $0 <command> [options]')
.command({
command: 'build',
describe: 'Build the React Native project',
builder: builderOptions,
builder: builderOptionsRun,
handler: buildHandler,
})
.command({
command: 'test',
describe: 'Runs the test suite',
builder: builderOptions,
builder: builderOptionsTest,
handler: runHandler,
})
.help('help')
Expand Down
35 changes: 31 additions & 4 deletions src/cli/run.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import path from 'path';
import execa, { ExecaSyncReturnValue } from 'execa';

import { BuildRunOptions, Config } from './types';
import { CliRunOptions, Config } from './types';
import { Logger } from '../logger';
import * as configHelpers from './config';
import * as run from './run';
Expand Down Expand Up @@ -167,7 +167,8 @@ describe('run.ts', () => {
const args = {
platform: 'ios',
config: './owl.config.json',
} as BuildRunOptions;
update: false,
} as CliRunOptions;

const config: Config = {
ios: {
Expand Down Expand Up @@ -204,7 +205,11 @@ describe('run.ts', () => {
await expect(mockRunIOS).toHaveBeenCalled();
await expect(commandSyncMock).toHaveBeenCalledTimes(1);
await expect(commandSyncMock).toHaveBeenCalledWith(expectedJestCommand, {
env: { OWL_DEBUG: 'false', OWL_PLATFORM: 'ios' },
env: {
OWL_DEBUG: 'false',
OWL_PLATFORM: 'ios',
OWL_UPDATE_BASELINE: 'false',
},
stdio: 'inherit',
});
});
Expand All @@ -220,7 +225,29 @@ describe('run.ts', () => {
await expect(mockRunAndroid).toHaveBeenCalled();
await expect(commandSyncMock).toHaveBeenCalledTimes(1);
await expect(commandSyncMock).toHaveBeenCalledWith(expectedJestCommand, {
env: { OWL_DEBUG: 'false', OWL_PLATFORM: 'android' },
env: {
OWL_DEBUG: 'false',
OWL_PLATFORM: 'android',
OWL_UPDATE_BASELINE: 'false',
},
stdio: 'inherit',
});
});

it('runs with the the update baseline flag on', async () => {
jest.spyOn(configHelpers, 'getConfig').mockResolvedValueOnce(config);
const mockRunIOS = jest.spyOn(run, 'runIOS').mockResolvedValueOnce();

await run.runHandler({ ...args, update: true });

await expect(mockRunIOS).toHaveBeenCalled();
await expect(commandSyncMock).toHaveBeenCalledTimes(1);
await expect(commandSyncMock).toHaveBeenCalledWith(expectedJestCommand, {
env: {
OWL_DEBUG: 'false',
OWL_PLATFORM: 'ios',
OWL_UPDATE_BASELINE: 'true',
},
stdio: 'inherit',
});
});
Expand Down
18 changes: 16 additions & 2 deletions src/cli/run.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import path from 'path';
import execa from 'execa';

import { BuildRunOptions, Config } from './types';
import { CliRunOptions, Config } from './types';
import { Logger } from '../logger';
import { getConfig } from './config';

Expand Down Expand Up @@ -53,7 +53,7 @@ export const runAndroid = async (config: Config, logger: Logger) => {
await execa.command(launchCommand, { stdio });
};

export const runHandler = async (args: BuildRunOptions) => {
export const runHandler = async (args: CliRunOptions) => {
const config = await getConfig(args.config);
const logger = new Logger(config.debug);
const runProject = args.platform === 'ios' ? runIOS : runAndroid;
Expand All @@ -64,6 +64,14 @@ export const runHandler = async (args: BuildRunOptions) => {
const jestConfigPath = path.join(__dirname, '..', 'jest-config.json');
const jestCommand = `jest --config=${jestConfigPath} --roots=${process.cwd()}`;

logger.print(
`[OWL] ${
args.update
? '(Update mode) Updating baseline images'
: '(Tests mode) Will compare latest images with the baseline'
}.`
);

logger.info(`[OWL] Will use the jest config localed at ${jestConfigPath}.`);
logger.info(`[OWL] Will set the jest root to ${process.cwd()}.`);

Expand All @@ -72,8 +80,14 @@ export const runHandler = async (args: BuildRunOptions) => {
env: {
OWL_PLATFORM: args.platform,
OWL_DEBUG: String(!!config.debug),
OWL_UPDATE_BASELINE: String(!!args.update),
},
});

logger.print(`[OWL] Tests completed on ${args.platform}.`);
if (args.update) {
logger.print(
`[OWL] All baseline images for ${args.platform} have been updated successfully.`
);
}
};
8 changes: 7 additions & 1 deletion src/cli/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@ import { Arguments } from 'yargs';

export type Platform = 'ios' | 'android';

export interface BuildRunOptions extends Arguments {
export interface CliBuildOptions extends Arguments {
platform: Platform;
config: string;
}

export interface CliRunOptions extends Arguments {
platform: Platform;
config: string;
update: boolean;
}

type ConfigIOS = {
/** The workspace to build. */
workspace?: string;
Expand Down
108 changes: 80 additions & 28 deletions src/take-screenshot.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,43 +15,95 @@ describe('take-screenshot.ts', () => {
commandMock.mockReset();
});

describe('iOS', () => {
describe('Baseline', () => {
beforeAll(() => {
process.env.OWL_PLATFORM = 'ios';
process.env.OWL_DEBUG = 'false';
process.env.OWL_UPDATE_BASELINE = 'true';
});

it('should take a screenshot', async () => {
await takeScreenshot();

expect(commandMock).toHaveBeenCalledWith(
'xcrun simctl io booted screenshot screen.png',
{
cwd: path.join(process.cwd(), '.owl', 'ios'),
shell: false,
stdio: 'ignore',
}
);
describe('iOS', () => {
beforeAll(() => {
process.env.OWL_PLATFORM = 'ios';
process.env.OWL_DEBUG = 'false';
});

it('should take a screenshot', async () => {
await takeScreenshot();

expect(commandMock).toHaveBeenCalledWith(
'xcrun simctl io booted screenshot screen.png',
{
cwd: path.join(process.cwd(), '.owl', 'baseline', 'ios'),
shell: false,
stdio: 'ignore',
}
);
});
});

describe('Android', () => {
beforeAll(() => {
process.env.OWL_PLATFORM = 'android';
process.env.OWL_DEBUG = 'false';
});

it('should take a screenshot', async () => {
await takeScreenshot();

expect(commandMock).toHaveBeenCalledWith(
'adb exec-out screencap -p > screen.png',
{
cwd: path.join(process.cwd(), '.owl', 'baseline', 'android'),
shell: true,
stdio: 'ignore',
}
);
});
});
});

describe('Android', () => {
describe('Latest', () => {
beforeAll(() => {
process.env.OWL_PLATFORM = 'android';
process.env.OWL_DEBUG = 'false';
process.env.OWL_UPDATE_BASELINE = 'false';
});

it('should take a screenshot', async () => {
await takeScreenshot();

expect(commandMock).toHaveBeenCalledWith(
'adb exec-out screencap -p > screen.png',
{
cwd: path.join(process.cwd(), '.owl', 'android'),
shell: true,
stdio: 'ignore',
}
);
describe('iOS', () => {
beforeAll(() => {
process.env.OWL_PLATFORM = 'ios';
process.env.OWL_DEBUG = 'false';
});

it('should take a screenshot', async () => {
await takeScreenshot();

expect(commandMock).toHaveBeenCalledWith(
'xcrun simctl io booted screenshot screen.png',
{
cwd: path.join(process.cwd(), '.owl', 'latest', 'ios'),
shell: false,
stdio: 'ignore',
}
);
});
});

describe('Android', () => {
beforeAll(() => {
process.env.OWL_PLATFORM = 'android';
process.env.OWL_DEBUG = 'false';
});

it('should take a screenshot', async () => {
await takeScreenshot();

expect(commandMock).toHaveBeenCalledWith(
'adb exec-out screencap -p > screen.png',
{
cwd: path.join(process.cwd(), '.owl', 'latest', 'android'),
shell: true,
stdio: 'ignore',
}
);
});
});
});
});
6 changes: 4 additions & 2 deletions src/take-screenshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ import { Logger } from './logger';
export const takeScreenshot = async (): Promise<void> => {
const platform = process.env.OWL_PLATFORM as Platform;
const debug = process.env.OWL_DEBUG === 'true';
const updateBaseline = process.env.OWL_UPDATE_BASELINE === 'true';

const stdio = debug ? 'inherit' : 'ignore';
const logger = new Logger(!!debug);

const DEFAULT_FILENAME = 'screen.png';
const DIR_NAME = '.owl';
const cwd = path.join(process.cwd(), DIR_NAME, platform);
const DIR_NAME = updateBaseline ? 'baseline' : 'latest';
const cwd = path.join(process.cwd(), '.owl', DIR_NAME, platform);

await fs.mkdir(cwd, { recursive: true });

Expand Down