diff --git a/.gitignore b/.gitignore index 7c40b95ca..b68953490 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ oclif.manifest.json .local-chromium packages/logger/test/client.js packages/sdk-utils/test/client.js +packs diff --git a/package.json b/package.json index 77df5999d..ae23e70ae 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "scripts": { "build": "lerna run build --stream", "build:watch": "lerna run build --stream -- --watch", + "build:pack": "mkdir -p ./packs && lerna exec npm pack && mv ./packages/*/*.tgz ./packs", "bump-version": "lerna version --exact --no-git-tag-version --no-push", "chromium-revision": "./scripts/chromium-revision", "clean": "git clean -Xdf -e !node_modules -e !**/node_modules/**", diff --git a/packages/cli/test/commands.test.js b/packages/cli/test/commands.test.js index c994293de..5046a9169 100644 --- a/packages/cli/test/commands.test.js +++ b/packages/cli/test/commands.test.js @@ -5,9 +5,8 @@ import { importCommands } from '../src/commands.js'; describe('CLI commands', () => { beforeEach(async () => { - await logger.mock(); - logger.loglevel('debug'); - mockfs({ $modules: true }); + await logger.mock({ level: 'debug' }); + await mockfs({ $modules: true }); }); describe('from node_modules', () => { @@ -30,28 +29,28 @@ describe('CLI commands', () => { ]; it('imports from dependencies', async () => { - mockModuleCommands(path.resolve('.'), mockCmds); + await mockModuleCommands(path.resolve('.'), mockCmds); await expectAsync(importCommands()).toBeResolvedTo(expectedCmds); expect(logger.stdout).toEqual([]); expect(logger.stderr).toEqual([]); }); it('imports from a parent directory', async () => { - mockModuleCommands(path.resolve('../..'), mockCmds); + await mockModuleCommands(path.resolve('../..'), mockCmds); await expectAsync(importCommands()).toBeResolvedTo(expectedCmds); expect(logger.stdout).toEqual([]); expect(logger.stderr).toEqual([]); }); it('imports from the current project', async () => { - mockModuleCommands(process.cwd(), mockCmds); + await mockModuleCommands(process.cwd(), mockCmds); await expectAsync(importCommands()).toBeResolvedTo(expectedCmds); expect(logger.stdout).toEqual([]); expect(logger.stderr).toEqual([]); }); it('automatically includes package information', async () => { - mockModuleCommands(path.resolve('.'), mockCmds); + await mockModuleCommands(path.resolve('.'), mockCmds); let cmds = await importCommands(); expect(cmds[0].packageInformation.name).toEqual('@percy/cli-config'); @@ -96,7 +95,7 @@ describe('CLI commands', () => { describe('legacy support', () => { it('transforms oclif-like classes', async () => { - mockLegacyCommands(process.cwd(), { + await mockLegacyCommands(process.cwd(), { '@percy/cli-legacy': { name: 'a' }, '@percy/cli-legacy-topic': { name: 'b', index: true }, '@percy/cli-legacy-index': { name: 'c', topic: true } @@ -125,7 +124,7 @@ describe('CLI commands', () => { it('runs oclif init hooks', async () => { let init = jasmine.createSpy('init'); - mockLegacyCommands(process.cwd(), { + await mockLegacyCommands(process.cwd(), { 'percy-cli-legacy': { name: 'test', init } }); diff --git a/packages/cli/test/helpers.js b/packages/cli/test/helpers.js index 8f97b3c3b..8a89011b5 100644 --- a/packages/cli/test/helpers.js +++ b/packages/cli/test/helpers.js @@ -10,9 +10,9 @@ export function mockUpdateCache(data, createdAt = Date.now()) { } // Mocks the filesystem and require cache to simulate installed commands -export function mockModuleCommands(atPath, cmdMocks) { +export async function mockModuleCommands(atPath, cmdMocks) { let modulesPath = `${atPath}/node_modules`; - let vol = mockfs({ $modules: true, [modulesPath]: null }); + let vol = await mockfs({ $modules: true, [modulesPath]: null }); let write = (rel, str) => vol.fromJSON({ [`${modulesPath}/${rel}`]: str }); // for coverage @@ -57,7 +57,7 @@ export async function mockPnpCommands(atPath, cmdMocks) { findPackageLocator.withArgs(projectInfo.packageLocation).and.returnValue(projectLoc); getPackageInformation.withArgs(projectLoc).and.returnValue(projectInfo); - let vol = mockfs({ $modules: true }); + let vol = await mockfs({ $modules: true }); let pnpPath = path.join('/.yarn/berry/cache'); let write = (fp, str) => vol.fromJSON({ [`${pnpPath}/${fp}`]: str }); @@ -80,9 +80,9 @@ export async function mockPnpCommands(atPath, cmdMocks) { } // Mocks the filesystem and require cache to simulate installed legacy commands -export function mockLegacyCommands(atPath, cmdMocks) { +export async function mockLegacyCommands(atPath, cmdMocks) { let modulesPath = `${atPath}/node_modules`; - let vol = mockfs({ $modules: true, [modulesPath]: null }); + let vol = await mockfs({ $modules: true, [modulesPath]: null }); let write = (fp, str) => vol.fromJSON({ [`${modulesPath}/${fp}`]: str }); for (let [pkgName, cmdMock] of Object.entries(cmdMocks)) { diff --git a/packages/cli/test/update.test.js b/packages/cli/test/update.test.js index 032295813..0ce678757 100644 --- a/packages/cli/test/update.test.js +++ b/packages/cli/test/update.test.js @@ -7,7 +7,7 @@ describe('CLI update check', () => { beforeEach(async () => { let pkg = { name: '@percy/cli', version: '1.0.0' }; - mockfs({ './package.json': JSON.stringify(pkg) }); + await mockfs({ './package.json': JSON.stringify(pkg) }); ghAPI = await mockRequests('https://api.github.com'); await logger.mock(); }); diff --git a/packages/config/package.json b/packages/config/package.json index 84ded2fc0..7180a9917 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -16,7 +16,7 @@ "files": [ "dist", "types/index.d.ts", - "tests/helpers.js" + "test/helpers.js" ], "main": "./dist/index.js", "types": "./types/index.d.ts", diff --git a/packages/config/test/helpers.js b/packages/config/test/helpers.js index 6413b09b0..a50e54fa5 100644 --- a/packages/config/test/helpers.js +++ b/packages/config/test/helpers.js @@ -3,14 +3,13 @@ import os from 'os'; import url from 'url'; import path from 'path'; import Module from 'module'; -import { Volume, createFsFromVolume } from 'memfs'; - -import { clearMigrations } from '../src/migrate.js'; -import { resetSchema } from '../src/validate.js'; -import { cache } from '../src/load.js'; // Reset various global @percy/config internals for testing -export function resetPercyConfig(all) { +export async function resetPercyConfig(all) { + // aliased to src during tests + let { clearMigrations } = await import('../dist/migrate.js'); + let { resetSchema } = await import('../dist/validate.js'); + let { cache } = await import('../dist/load.js'); if (all) clearMigrations(); if (all) resetSchema(); cache.clear(); @@ -30,7 +29,7 @@ const INTERNAL_FILE_REG = new RegExp( ); // Mock and spy on fs methods using an in-memory filesystem -export function mockfs({ +export async function mockfs({ // set `true` to allow mocking files within `node_modules` (may cause dynamic import issues) $modules = false, // list of filepaths or function matchers to allow direct access to the real filesystem @@ -38,7 +37,8 @@ export function mockfs({ // initial flat map of files and/or directories to create ...initial } = {}) { - let vol = new Volume(); + let memfs = await import('memfs'); + let vol = new memfs.Volume(); // automatically cleanup mock imports global.__MOCK_IMPORTS__?.clear(); @@ -81,7 +81,7 @@ export function mockfs({ }; // mock and install fs methods using the in-memory filesystem - let mock = createFsFromVolume(vol); + let mock = memfs.createFsFromVolume(vol); installFakes(fs.promises, mock.promises); installFakes(fs, mock); diff --git a/packages/config/test/index.test.js b/packages/config/test/index.test.js index 634f9ace7..1e5d359ba 100644 --- a/packages/config/test/index.test.js +++ b/packages/config/test/index.test.js @@ -4,9 +4,9 @@ import PercyConfig from '@percy/config'; describe('PercyConfig', () => { beforeEach(async () => { + await resetPercyConfig(true); await logger.mock(); - resetPercyConfig(true); - mockfs(); + await mockfs(); PercyConfig.addSchema({ test: { diff --git a/packages/core/package.json b/packages/core/package.json index 4ad8f50de..7d8f0109c 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -27,7 +27,8 @@ "./utils": "./dist/utils.js", "./config": "./dist/config.js", "./install": "./dist/install.js", - "./test/helpers": "./test/helpers/index.js" + "./test/helpers": "./test/helpers/index.js", + "./test/helpers/server": "./test/helpers/server.js" }, "scripts": { "build": "node ../../scripts/build", diff --git a/packages/core/test/helpers/index.js b/packages/core/test/helpers/index.js index e46e28056..c42121709 100644 --- a/packages/core/test/helpers/index.js +++ b/packages/core/test/helpers/index.js @@ -22,10 +22,10 @@ export async function setupTest({ loggerTTY, apiDelay } = {}) { - await logger.mock({ isTTY: loggerTTY }); await api.mock({ delay: apiDelay }); - resetPercyConfig(resetConfig); - mockfs(filesystem); + await logger.mock({ isTTY: loggerTTY }); + await resetPercyConfig(resetConfig); + await mockfs(filesystem); } export * from '@percy/client/test/helpers'; diff --git a/packages/core/test/helpers/server.js b/packages/core/test/helpers/server.js index 532211c8a..05a1b5c4b 100644 --- a/packages/core/test/helpers/server.js +++ b/packages/core/test/helpers/server.js @@ -1,4 +1,4 @@ -// aliased to src for coverage during tests without needing to compile this file +// aliased to src during tests import Server from '../../dist/server.js'; export function createTestServer({ default: defaultReply, ...replies }, port = 8000) { diff --git a/packages/core/test/unit/install.test.js b/packages/core/test/unit/install.test.js index af29c21a0..d2df10c31 100644 --- a/packages/core/test/unit/install.test.js +++ b/packages/core/test/unit/install.test.js @@ -11,7 +11,7 @@ describe('Unit / Install', () => { beforeEach(async () => { await logger.mock({ isTTY: true }); - mockfs(); + await mockfs(); // mock a fake download api dl = await mockRequests('https://fake-download.org/archive.zip'); diff --git a/packages/core/test/unit/server.test.js b/packages/core/test/unit/server.test.js index c2b2d515b..42bef97d6 100644 --- a/packages/core/test/unit/server.test.js +++ b/packages/core/test/unit/server.test.js @@ -9,9 +9,9 @@ describe('Unit / Server', () => { return request(new URL(path, server.address()), ...args); } - beforeEach(() => { + beforeEach(async () => { server = new Server({ port: 8000 }); - mockfs(); + await mockfs(); }); afterEach(async () => { diff --git a/packages/logger/test/helpers.js b/packages/logger/test/helpers.js index 530490935..4c14007ca 100644 --- a/packages/logger/test/helpers.js +++ b/packages/logger/test/helpers.js @@ -46,6 +46,10 @@ const helpers = { async mock(options = {}) { helpers.reset(); + if (options.level) { + loglevel(options.level); + } + if (process.env.__PERCY_BROWSERIFIED__) { spy(Logger.prototype, 'write', function(lvl, msg) { let stdio = lvl === 'info' ? 'stdout' : 'stderr'; diff --git a/packages/sdk-utils/test/server.js b/packages/sdk-utils/test/server.js index 11dbf5e37..9ad54fb53 100644 --- a/packages/sdk-utils/test/server.js +++ b/packages/sdk-utils/test/server.js @@ -4,7 +4,7 @@ import path from 'path'; // create a testing context for mocking the local percy server and a local testing site export async function context() { - let { createTestServer } = await import('@percy/core/test/helpers'); + let { createTestServer } = await import('@percy/core/test/helpers/server'); let ctx = { async call(path, ...args) {