Skip to content

Commit

Permalink
tests: add basic e2e tests involving libs (BOSL2 & NopSCADlib)
Browse files Browse the repository at this point in the history
  • Loading branch information
ochafik committed Dec 25, 2024
1 parent 7bc180a commit 5f1b34b
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 25 deletions.
9 changes: 8 additions & 1 deletion src/state/fragment-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { State } from "./app-state";
import { VALID_EXPORT_FORMATS_2D, VALID_EXPORT_FORMATS_3D, VALID_RENDER_FORMATS } from './formats';
import { validateArray, validateBoolean, validateString, validateStringEnum } from "../utils";
import { defaultModelColor, defaultSourcePath } from "./initial-state";
import { createInitialState, defaultModelColor, defaultSourcePath } from "./initial-state";

export function buildUrlForStateParams(state: State) {//partialState: {params: State['params'], view: State['view']}) {
return `${location.protocol}//${location.host}${location.pathname}#${encodeStateParamsAsFragment(state)}`;
Expand Down Expand Up @@ -51,6 +51,13 @@ export async function readStateFromFragment(): Promise<State | null> {
if (window.location.hash.startsWith('#') && window.location.hash.length > 1) {
try {
const serialized = window.location.hash.substring(1);
if (serialized === 'blank') {
return createInitialState(null, '');
} else if (serialized.startsWith('src:')) {
// For testing
const src = decodeURIComponent(serialized.substring('src:'.length));
return createInitialState(null, src);
}
let obj;
try {
obj = JSON.parse(await decompressString(serialized));
Expand Down
97 changes: 73 additions & 24 deletions tests/e2e.test.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,79 @@
const longTimeout = 60000;

const isProd = process.env.NODE_ENV === 'production';
const url = isProd ? 'http://localhost:3000/dist/' : 'http://localhost:4000';
const url = isProd ? 'http://localhost:3000/dist/' : 'http://localhost:4000/';

describe('e2e', () => {
test('should load the page', async () => {
const messages = [];
page.on('console', (msg) => messages.push({type: msg.type(), text: msg.text(), stack: msg.stackTrace(), location: msg.location()}));
page.goto(url);
await page.waitForSelector('model-viewer');

await page.waitForFunction(() => {
const viewer = document.querySelector('model-viewer.main-viewer');
return viewer && viewer.src !== '';
});

console.log('Messages:', JSON.stringify(messages, null, 2));
const messages = [];

beforeAll(async () => {
page.on('console', (msg) => messages.push({
type: msg.type(),
text: msg.text(),
stack: msg.stackTrace(),
location: msg.location(),
}));
});

beforeEach(async () => {
messages.length = 0;
await page.goto('about:blank');
});

afterEach(async () => {
// console.log('Messages:', JSON.stringify(messages, null, 2));
console.log('Messages:', JSON.stringify(messages.map(({text}) => text), null, 2));

const errors = messages.filter(msg =>
msg.type === 'error' &&
!(msg.text.includes('404')
&& msg.stack.some(s =>
s.url.indexOf('fonts/InterVariable.woff') >= 0)));
expect(errors).toHaveLength(0);

const successMessage = messages.filter(msg => msg.type === 'debug' && msg.text === 'stderr: Top level object is a list of objects:');
expect(successMessage).toHaveLength(1);
const errors = messages.filter(msg =>
msg.type === 'error' &&
!(msg.text.includes('404')
&& msg.stack.some(s =>
s.url.indexOf('fonts/InterVariable.woff') >= 0)));
expect(errors).toHaveLength(0);
});

function loadSrc(src) {
return page.goto(url + '#src:' + encodeURIComponent(src));
}
async function waitForViewer() {
await page.waitForSelector('model-viewer');
await page.waitForFunction(() => {
const viewer = document.querySelector('model-viewer.main-viewer');
return viewer && viewer.src !== '';
});
}
function expectMessage(messages, line) {
const successMessage = messages.filter(msg => msg.type === 'debug' && msg.text === line);
expect(successMessage).toHaveLength(1);
}

describe('e2e', () => {
test('load the default page', async () => {
await page.goto(url);
await waitForViewer();
expectMessage(messages, 'stderr: Top level object is a list of objects:');
}, longTimeout);

test('can render cube', async () => {
await loadSrc('cube([10, 10, 10]);');
await waitForViewer();
expectMessage(messages, 'stderr: Top level object is a 3D object (PolySet):');
}, longTimeout);

test('use BOSL2', async () => {
await loadSrc(`
include <BOSL2/std.scad>;
prismoid([40,40], [0,0], h=20);
`);
await waitForViewer();
expectMessage(messages, 'stderr: Top level object is a 3D object (PolySet):');
}, longTimeout);

test('use NopSCADlib', async () => {
await loadSrc(`
include <NopSCADlib/vitamins/led_meters.scad>
meter(led_meter);
`);
await waitForViewer();
expectMessage(messages, 'stderr: Top level object is a 3D object (manifold):');
}, longTimeout);
});
});

0 comments on commit 5f1b34b

Please sign in to comment.