Skip to content

Commit

Permalink
feat: custom transform for bundling and running suites
Browse files Browse the repository at this point in the history
  • Loading branch information
vigneshshanmugam committed Dec 20, 2022
1 parent 88a8fac commit 615882f
Show file tree
Hide file tree
Showing 13 changed files with 490 additions and 957 deletions.
128 changes: 5 additions & 123 deletions __tests__/push/__snapshots__/plugin.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,129 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Plugin bundle jouneys 1`] = `
"/**
* MIT License
*
* Copyright (c) 2020-present, Elastic NV
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the \\"Software\\"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED \\"AS IS\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
import { beforeAll, journey, step } from '@elastic/synthetics';
import axios from 'axios';
beforeAll(async () => {
await waitForElasticSearch();
await waitForSyntheticsData();
await waitForKibana();
});
journey('E2e test synthetics', async ({ page }) => {
async function refreshUptimeApp() {
while (!(await page.$('div.euiBasicTable'))) {
await page.click('[data-test-subj=superDatePickerApplyTimeButton]', {
timeout: 60 * 1000,
});
}
}
step('Go to kibana uptime app', async () => {
await page.goto('http://localhost:5620/app/uptime', {
waitUntil: 'networkidle',
});
});
step('Check if there is table data', async () => {
await page.click('[data-test-subj=uptimeOverviewPage]', {
timeout: 60 * 1000,
});
await refreshUptimeApp();
await page.click('div.euiBasicTable', { timeout: 60 * 1000 });
});
step('Click on my monitor', async () => {
await page.click('[data-test-subj=monitor-page-link-my-monitor]');
});
step('It navigates to details page', async () => {
await page.click('[data-test-subj=uptimeMonitorPage]');
exports[`SyntheticsBundlePlugin skip locally resolved synthetics package 1`] = `
"var import__ = require(\\"../../\\");
(0, import__.journey)(\\"journey 1\\", () => {
import__.monitor.use({ id: \\"duplicate id\\" });
(0, import__.step)(\\"step1\\", () => {
});
});
async function waitForSyntheticsData() {
console.log('Waiting for Synthetics to send data to ES for test monitor');
let status = false;
while (!status) {
try {
const { data } = await axios.post(
'http://localhost:9220/heartbeat-*/_search',
{
query: {
bool: {
filter: [
{
term: {
'monitor.id': 'my-monitor',
},
},
{
exists: {
field: 'summary',
},
},
],
},
},
}
);
// we want some data in uptime app
status = data?.hits.total.value >= 2;
} catch (e) {}
}
}
async function waitForElasticSearch() {
console.log('Waiting for Elastic Search to start');
let esStatus = false;
while (!esStatus) {
try {
const { data } = await axios.get('http://localhost:9220/_cluster/health');
esStatus = data?.status !== 'red';
} catch (e) {}
}
}
async function waitForKibana() {
console.log('Waiting for kibana server to start');
let esStatus = false;
while (!esStatus) {
try {
const { data } = await axios.get('http://localhost:5620/api/status');
esStatus = data?.status.overall.level === 'available';
} catch (e) {}
}
}
"
`;
68 changes: 40 additions & 28 deletions __tests__/push/bundler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,34 @@ import { Bundler } from '../../src/push/bundler';
const PROJECT_DIR = join(__dirname, 'test-bundler');
const journeyFile = join(PROJECT_DIR, 'bundle.journey.ts');

const setup = async () => {
await writeFile(
journeyFile,
`import {journey, step, monitor} from '@elastic/synthetics';
import isPositive from 'is-positive';
import utils from "./utils"
journey('journey 1', () => {
// avoid dead code elimination
utils();
monitor.use({ id: 'duplicate id' });
launchStep(-1);
});
const launchStep = (no: number) => {
step("step1", () => {
isPositive(no);
})
};`
);

await writeFile(
join(PROJECT_DIR, 'utils.ts'),
`import isPositive from 'is-positive';
export default utils = () => {
isPositive(1);
};`
);
};

async function validateZip(content) {
const partialPath = join(
'__tests__',
Expand All @@ -46,27 +74,26 @@ async function validateZip(content) {

const files: Array<string> = [];

let targetFileContent = '';
let contents = '';
await new Promise(r => {
createReadStream(pathToZip)
.pipe(unzipper.Parse())
.on('entry', function (entry) {
const fileName = entry.path;
files.push(fileName);
if (fileName === partialPath) {
entry.on('data', d => (targetFileContent += d));
} else {
entry.autodrain();
}
files.push(entry.path);
contents += '\n' + entry.path + '\n';
entry.on('data', d => (contents += d));
})
.on('close', r);
});

expect(files).toEqual([partialPath]);

expect(targetFileContent).toContain('__toESM');
expect(targetFileContent).toContain('node_modules/is-positive/index.js');

// Verify if files are bundled together
expect(contents).toContain('node_modules/is-positive/index.js');
expect(contents).toContain('test-bundler/bundle.journey.ts');
expect(contents).toContain('test-bundler/utils.ts');
// Verify if sourcemaps are present after bundling
expect(contents).toContain('sourceMappingURL=data:application/json;base64');
await unlink(pathToZip);
}

Expand All @@ -75,22 +102,7 @@ describe('Bundler', () => {

beforeAll(async () => {
await mkdir(PROJECT_DIR, { recursive: true });
await writeFile(
journeyFile,
`import {journey, step, monitor} from '@elastic/synthetics';
import isPositive from 'is-positive';
journey('journey 1', () => {
monitor.use({ id: 'duplicate id' });
launchStep(-1);
});
const launchStep = (no: number) => {
step("step1", () => {
isPositive(no);
})
};`
);
await setup();
});

afterAll(async () => {
Expand All @@ -112,7 +124,7 @@ const launchStep = (no: number) => {
try {
await bundler.build(join(PROJECT_DIR, 'blah.ts'), generateTempPath());
} catch (e) {
expect(e.message).toContain('ENOENT');
expect(e.message).toContain('Build failed');
}
});
});
6 changes: 3 additions & 3 deletions __tests__/push/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ describe('Push', () => {
const testJourney = join(PROJECT_DIR, 'test.journey.ts');
await writeFile(
testJourney,
`import {journey, monitor} from '../../../src';
`import {journey, monitor} from '../../../';
journey('journey 1', () => monitor.use({ id: 'j1', schedule: 8 }));`
);
const output = await runPush();
Expand All @@ -139,7 +139,7 @@ journey('journey 1', () => monitor.use({ id: 'j1', schedule: 8 }));`
const dupJourney = join(PROJECT_DIR, 'duplicate.journey.ts');
await writeFile(
dupJourney,
`import {journey, monitor} from '../../../src';
`import {journey, monitor} from '../../../';
journey('journey 1', () => monitor.use({ id: 'duplicate id' }));
journey('journey 2', () => monitor.use({ id: 'duplicate id' }));
Expand Down Expand Up @@ -234,7 +234,7 @@ heartbeat.monitors:
const testJourney = join(PROJECT_DIR, 'test.journey.ts');
await writeFile(
testJourney,
`import {journey, monitor} from '../../../src/index';
`import {journey, monitor} from '../../../';
journey('journey 1', () => monitor.use({ id: 'j1' }));
journey('journey 2', () => monitor.use({ id: 'j2' }));`
);
Expand Down
52 changes: 30 additions & 22 deletions __tests__/push/plugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,33 +24,41 @@
*/

import * as esbuild from 'esbuild';
import { mkdir, rm, writeFile } from 'fs/promises';
import { join } from 'path';
import NodeResolve from '@esbuild-plugins/node-resolve';
import {
MultiAssetPlugin,
commonOptions,
PluginData,
} from '../../src/push/plugin';
import { commonOptions } from '../../src/core/transform';
import { SyntheticsBundlePlugin } from '../../src/push/plugin';

const E2E_DIR = join(__dirname, '..', 'e2e');
describe('SyntheticsBundlePlugin', () => {
const PROJECT_DIR = join(__dirname, 'test-bundler');
const journeyFile = join(PROJECT_DIR, 'bundle.journey.ts');

describe('Plugin', () => {
it('bundle jouneys', async () => {
const callback = (data: PluginData) => {
expect(data.path).toContain('e2e/uptime.journey.ts');
expect(data.contents).toMatchSnapshot();
};
beforeAll(async () => {
await mkdir(PROJECT_DIR, { recursive: true });
});

afterAll(async () => {
await rm(PROJECT_DIR, { recursive: true });
});

await esbuild.build({
it('skip locally resolved synthetics package', async () => {
// Should
await writeFile(
journeyFile,
`import {journey, step, monitor} from '../../';
journey('journey 1', () => {
monitor.use({ id: 'duplicate id' });
step("step1", () => {})
});`
);
const result = await esbuild.build({
...commonOptions(),
entryPoints: [join(E2E_DIR, 'uptime.journey.ts')],
plugins: [
MultiAssetPlugin(callback),
NodeResolve({
extensions: ['.ts', '.js'],
resolveOptions: { basedir: E2E_DIR },
}),
],
bundle: false,
sourcemap: false,
write: false,
entryPoints: [journeyFile],
plugins: [SyntheticsBundlePlugin()],
});
expect(result.outputFiles[0].text).toMatchSnapshot();
});
});
Loading

0 comments on commit 615882f

Please sign in to comment.