Skip to content
Draft
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
23 changes: 18 additions & 5 deletions packages/matrix/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ import {
} from '../docker/synapse';
import { realmPassword } from './realm-credentials';
import { appURL, BasicSQLExecutor, SQLExecutor } from './isolated-realm-server';
import { isEnvironmentMode, getEnvironmentSlug } from './environment-config';
import { APP_BOXEL_MESSAGE_MSGTYPE } from './matrix-constants';
import { randomUUID } from 'crypto';

export const testHost = 'http://localhost:4205/test';
export const testHost = appURL;
export const mailHost = 'http://localhost:5001';
export const initialRoomName = 'New AI Assistant Chat';
export const REGISTRATION_TOKEN = 'abc123';
Expand Down Expand Up @@ -107,15 +108,27 @@ async function registerRealmRedirect(
}

export async function setRealmRedirects(page: Page) {
let baseServerUrl: string;
let isolatedServerUrl: string;

if (isEnvironmentMode()) {
let slug = getEnvironmentSlug();
baseServerUrl = `http://realm-server.${slug}.localhost`;
isolatedServerUrl = `http://realm-matrix-test.${slug}.localhost`;
} else {
baseServerUrl = 'http://localhost:4201';
isolatedServerUrl = 'http://localhost:4205';
}

await registerRealmRedirect(
page,
'http://localhost:4201/skills/',
'http://localhost:4205/skills/',
`${baseServerUrl}/skills/`,
`${isolatedServerUrl}/skills/`,
);
await registerRealmRedirect(
page,
'http://localhost:4201/base/',
'http://localhost:4205/base/',
`${baseServerUrl}/base/`,
`${isolatedServerUrl}/base/`,
);
}

Expand Down
60 changes: 47 additions & 13 deletions packages/matrix/helpers/isolated-realm-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { ensureDirSync, copySync, readFileSync } from 'fs-extra';
import { Pool } from 'pg';
import { createServer as createNetServer, type AddressInfo } from 'net';
import type { SynapseInstance } from '../docker/synapse';
import { isEnvironmentMode, getEnvironmentSlug } from './environment-config';

setGracefulCleanup();

Expand All @@ -18,7 +19,23 @@ const skillsRealmDir = resolve(
);
const baseRealmDir = resolve(join(__dirname, '..', '..', 'base'));
const matrixDir = resolve(join(__dirname, '..'));
export const appURL = 'http://localhost:4205/test';

const ISOLATED_REALM_SERVICE = 'realm-matrix-test';
const ISOLATED_WORKER_SERVICE = 'worker-matrix-test';
const DEFAULT_REALM_PORT = 4205;

function getRealmBaseURL(): string {
if (isEnvironmentMode()) {
return `http://${ISOLATED_REALM_SERVICE}.${getEnvironmentSlug()}.localhost`;
}
return `http://localhost:${DEFAULT_REALM_PORT}`;
}

export const realmDomain = isEnvironmentMode()
? `${ISOLATED_REALM_SERVICE}.${getEnvironmentSlug()}.localhost`
: `localhost:${DEFAULT_REALM_PORT}`;

export const appURL = `${getRealmBaseURL()}/test`;

const DEFAULT_PRERENDER_PORT = 4231;

Expand Down Expand Up @@ -142,7 +159,11 @@ export async function startPrerenderServer(
...process.env,
NODE_ENV: process.env.NODE_ENV ?? 'development',
NODE_NO_WARNINGS: '1',
BOXEL_HOST_URL: process.env.HOST_URL ?? 'http://localhost:4200',
BOXEL_HOST_URL:
process.env.HOST_URL ??
(isEnvironmentMode()
? `http://host.${getEnvironmentSlug()}.localhost`
: 'http://localhost:4200'),
};
let prerenderArgs = [
'--transpileOnly',
Expand Down Expand Up @@ -216,6 +237,13 @@ export async function startServer({
let testDBName = `test_db_${Math.floor(10000000 * Math.random())}`;
let workerManagerPort = await findAvailablePort(4232);

let envMode = isEnvironmentMode();
let realmBaseURL = getRealmBaseURL();
let realmPort = envMode ? 0 : DEFAULT_REALM_PORT;
let realmDomain = envMode
? `${ISOLATED_REALM_SERVICE}.${getEnvironmentSlug()}.localhost`
: `localhost:${DEFAULT_REALM_PORT}`;

process.env.PGPORT = '5435';
process.env.PGDATABASE = testDBName;
process.env.NODE_NO_WARNINGS = '1';
Expand All @@ -236,13 +264,16 @@ export async function startServer({
`--prerendererUrl='${prerenderURL}'`,
`--migrateDB`,

`--fromUrl='http://localhost:4205/test/'`,
`--toUrl='http://localhost:4205/test/'`,
`--fromUrl='${realmBaseURL}/test/'`,
`--toUrl='${realmBaseURL}/test/'`,
];
workerArgs = workerArgs.concat([
`--fromUrl='https://cardstack.com/base/'`,
`--toUrl='http://localhost:4205/base/'`,
`--toUrl='${realmBaseURL}/base/'`,
]);
if (envMode) {
workerArgs.push(`--serviceName=${ISOLATED_WORKER_SERVICE}`);
}

let workerManager = spawn('ts-node', workerArgs, {
cwd: realmServerDir,
Expand All @@ -262,7 +293,7 @@ export async function startServer({
let serverArgs = [
`--transpileOnly`,
'main',
`--port=4205`,
`--port=${realmPort}`,
`--matrixURL='${matrixURL}'`,
`--realmsRootPath='${dir.name}'`,
`--workerManagerPort=${workerManagerPort}`,
Expand All @@ -271,21 +302,24 @@ export async function startServer({

`--path='${testRealmDir}'`,
`--username='test_realm'`,
`--fromUrl='http://localhost:4205/test/'`,
`--toUrl='http://localhost:4205/test/'`,
`--fromUrl='${realmBaseURL}/test/'`,
`--toUrl='${realmBaseURL}/test/'`,
];
serverArgs = serverArgs.concat([
`--username='skills_realm'`,
`--path='${skillsRealmDir}'`,
`--fromUrl='http://localhost:4205/skills/'`,
`--toUrl='http://localhost:4205/skills/'`,
`--fromUrl='${realmBaseURL}/skills/'`,
`--toUrl='${realmBaseURL}/skills/'`,
]);
serverArgs = serverArgs.concat([
`--username='base_realm'`,
`--path='${baseRealmDir}'`,
`--fromUrl='https://cardstack.com/base/'`,
`--toUrl='http://localhost:4205/base/'`,
`--toUrl='${realmBaseURL}/base/'`,
]);
if (envMode) {
serverArgs.push(`--serviceName=${ISOLATED_REALM_SERVICE}`);
}

console.log(`realm server database: ${testDBName}`);

Expand All @@ -294,8 +328,8 @@ export async function startServer({
stdio: ['pipe', 'pipe', 'pipe', 'ipc'],
env: {
...process.env,
PUBLISHED_REALM_BOXEL_SPACE_DOMAIN: 'localhost:4205',
PUBLISHED_REALM_BOXEL_SITE_DOMAIN: 'localhost:4205',
PUBLISHED_REALM_BOXEL_SPACE_DOMAIN: realmDomain,
PUBLISHED_REALM_BOXEL_SITE_DOMAIN: realmDomain,
},
});
realmServer.unref();
Expand Down
13 changes: 11 additions & 2 deletions packages/matrix/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
import { defineConfig, devices } from '@playwright/test';
import { appURL } from './helpers/isolated-realm-server';
import {
isEnvironmentMode,
getEnvironmentSlug,
} from './helpers/environment-config';

// In environment mode, the isolated realm server is behind Traefik on port 80.
// In non-env mode, it listens directly on port 4205.
let realmPort = isEnvironmentMode() ? 80 : 4205;

/**
* See https://playwright.dev/docs/test-configuration.
Expand All @@ -14,7 +23,7 @@ export default defineConfig({
reporter: process.env.CI ? 'blob' : 'html',
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
baseURL: 'http://localhost:4205/test',
baseURL: appURL,

/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'retry-with-trace',
Expand All @@ -35,7 +44,7 @@ export default defineConfig({
launchOptions: {
args: [
// Simulate resolving a custom workspace domain to a realm server
'--host-resolver-rules=MAP published.realm 127.0.0.1:4205',
`--host-resolver-rules=MAP published.realm 127.0.0.1:${realmPort}`,
// Allow iframe to request storage access depsite being considered insecure
'--unsafely-treat-insecure-origin-as-secure=http://published.realm',
],
Expand Down
6 changes: 3 additions & 3 deletions packages/matrix/tests/head-tags.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { test, expect } from './fixtures';
import type { Page } from '@playwright/test';
import { randomUUID } from 'crypto';
import { appURL } from '../helpers/isolated-realm-server';
import { appURL, realmDomain } from '../helpers/isolated-realm-server';
import {
clearLocalStorage,
createRealm,
Expand Down Expand Up @@ -82,7 +82,7 @@ test.describe('Head tags', () => {
}) => {
await publishDefaultRealm(page);

let publishedRealmURLString = `http://${user.username}.localhost:4205/new-workspace/index`;
let publishedRealmURLString = `http://${user.username}.${realmDomain}/new-workspace/index`;

await page.goto(publishedRealmURLString);

Expand Down Expand Up @@ -270,7 +270,7 @@ test.describe('Head tags', () => {
await page.locator('[data-test-publish-button]').click();
await page.waitForSelector('[data-test-unpublish-button]');

let publishedRealmURL = `http://${user.username}.localhost:4205/${realmName}/`;
let publishedRealmURL = `http://${user.username}.${realmDomain}/${realmName}/`;
let defaultCardURL = `${publishedRealmURL}default-head-card.json`;

await page.goto(defaultCardURL);
Expand Down
14 changes: 7 additions & 7 deletions packages/matrix/tests/host-mode.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
postCardSource,
waitUntil,
} from '../helpers';
import { appURL } from '../helpers/isolated-realm-server';
import { appURL, realmDomain } from '../helpers/isolated-realm-server';
import { randomUUID } from 'crypto';

test.describe('Host mode', () => {
Expand Down Expand Up @@ -185,10 +185,10 @@ test.describe('Host mode', () => {
await page.reload();
await page.locator('[data-test-host-mode-isolated]').waitFor();

publishedRealmURL = `http://published.localhost:4205/${username}/${realmName}/`;
publishedRealmURL = `http://published.${realmDomain}/${username}/${realmName}/`;

await page.evaluate(
async ({ realmURL, publishedRealmURL }) => {
async ({ realmURL, publishedRealmURL, serverOrigin }) => {
let sessions = JSON.parse(
window.localStorage.getItem('boxel-session') ?? '{}',
);
Expand All @@ -197,7 +197,7 @@ test.describe('Host mode', () => {
throw new Error(`No session token found for ${realmURL}`);
}

let response = await fetch('http://localhost:4205/_publish-realm', {
let response = await fetch(`${serverOrigin}/_publish-realm`, {
method: 'POST',
headers: {
Accept: 'application/json',
Expand All @@ -216,13 +216,13 @@ test.describe('Host mode', () => {

return response.json();
},
{ realmURL, publishedRealmURL },
{ realmURL, publishedRealmURL, serverOrigin: serverIndexUrl },
);

publishedCardURL = `${publishedRealmURL}index.json`;
publishedWhitePaperCardURL = `${publishedRealmURL}white-paper.json`;
publishedMyCardURL = `${publishedRealmURL}my-card.json`;
connectRouteURL = `http://localhost:4205/connect/${encodeURIComponent(
connectRouteURL = `${serverIndexUrl}/connect/${encodeURIComponent(
publishedRealmURL,
)}`;

Expand Down Expand Up @@ -322,7 +322,7 @@ test.describe('Host mode', () => {
page,
}) => {
let response = await page.goto(
'http://localhost:4205/connect/http%3A%2F%2Fexample.com',
`${serverIndexUrl}/connect/http%3A%2F%2Fexample.com`,
);

expect(response?.status()).toBe(404);
Expand Down
14 changes: 7 additions & 7 deletions packages/matrix/tests/publish-realm.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { test, expect } from './fixtures';
import type { Page } from '@playwright/test';
import { appURL } from '../helpers/isolated-realm-server';
import { appURL, realmDomain } from '../helpers/isolated-realm-server';
import {
clearLocalStorage,
createRealm,
Expand Down Expand Up @@ -60,11 +60,11 @@ test.describe('Publish realm', () => {
await newTab.waitForLoadState();

await expect(newTab).toHaveURL(
`http://${user.username}.localhost:4205/new-workspace/`,
`http://${user.username}.${realmDomain}/new-workspace/`,
);
await expect(
newTab.locator(
`[data-test-card="http://${user.username}.localhost:4205/new-workspace/index"]`,
`[data-test-card="http://${user.username}.${realmDomain}/new-workspace/index"]`,
),
).toBeVisible();
await newTab.close();
Expand Down Expand Up @@ -119,11 +119,11 @@ test.describe('Publish realm', () => {
await newTab.waitForLoadState();

await expect(newTab).toHaveURL(
'http://acceptable-subdomain.localhost:4205/',
`http://acceptable-subdomain.${realmDomain}/`,
);
await expect(
newTab.locator(
'[data-test-card="http://acceptable-subdomain.localhost:4205/index"]',
`[data-test-card="http://acceptable-subdomain.${realmDomain}/index"]`,
),
).toBeVisible();
await newTab.close();
Expand Down Expand Up @@ -251,7 +251,7 @@ test.describe('Publish realm', () => {
await newTab.waitForLoadState();

await expect(newTab).toHaveURL(
`http://${user.username}.localhost:4205/new-workspace/`,
`http://${user.username}.${realmDomain}/new-workspace/`,
);
await newTab.close();
await page.bringToFront();
Expand Down Expand Up @@ -281,7 +281,7 @@ test.describe('Publish realm', () => {
await newTab.waitForLoadState();

await expect(newTab).toHaveURL(
`http://${user.username}.localhost:4205/new-workspace/`,
`http://${user.username}.${realmDomain}/new-workspace/`,
);
await newTab.close();
await page.bringToFront();
Expand Down
2 changes: 1 addition & 1 deletion packages/matrix/tests/registration-with-token.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ test.describe('User Registration w/ Token', () => {
APP_BOXEL_REALMS_EVENT_TYPE,
);
expect(realms).toEqual({
realms: [`http://localhost:4205/${firstUser.username}/personal/`],
realms: [`${serverIndexUrl}/${firstUser.username}/personal/`],
});
});

Expand Down
6 changes: 3 additions & 3 deletions packages/matrix/tests/skills.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ test.describe('Skills', () => {
).toContainClass('checked');
}

const environmentSkillCardId = `http://localhost:4205/skills/Skill/boxel-environment`;
const serverIndexUrl = new URL(appURL).origin;
const environmentSkillCardId = `${serverIndexUrl}/skills/Skill/boxel-environment`;
const defaultSkillCardsForCodeMode = [
`http://localhost:4205/skills/Skill/boxel-development`,
`${serverIndexUrl}/skills/Skill/boxel-development`,
environmentSkillCardId,
];
const skillCard1 = `${appURL}/skill-pirate-speak`;
const skillCard2 = `${appURL}/skill-seo`;
const skillCard3 = `${appURL}/skill-card-title-editing`;
const serverIndexUrl = new URL(appURL).origin;

test(`it can attach skill cards and toggle activation`, async ({ page }) => {
await login(page, firstUser.username, firstUser.password, { url: appURL });
Expand Down
Loading
Loading