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
9 changes: 4 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ jobs:
with:
version: 10.30.3

- name: Build RSC plugin
run: pnpm build

- name: Setup Node.js
uses: actions/setup-node@v6
with:
Expand All @@ -44,7 +41,9 @@ jobs:
- name: Install dependencies
run: pnpm install

- name: Build RSC plugin
run: pnpm build

- name: Publish to npm
run: pnpm publish --provenance --access public --no-git-checks --tag ${{ inputs.tag }}
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

14 changes: 13 additions & 1 deletion e2e/helper/jsApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ export type BuildOptions = CreateRsbuildOptions & {
* @default false
*/
runServer?: boolean;
/**
* Whether to start preview server after build.
* @default false
*/
preview?: boolean;
/**
* Playwright Page instance.
* This method will automatically run the server and goto the page.
Expand All @@ -182,6 +187,7 @@ export type BuildOptions = CreateRsbuildOptions & {
export async function build({
catchBuildError = false,
runServer = false,
preview = false,
watch = false,
page,
logHelper,
Expand Down Expand Up @@ -213,6 +219,12 @@ export async function build({
let port = 0;
let server = { close: noop };

if (preview) {
const result = await rsbuild.preview();
port = result.port;
server = result.server;
}

if (runServer) {
port = await getRandomPort();

Expand All @@ -234,7 +246,7 @@ export async function build({
resolve();
});
server = {
close() {
async close() {
theServer.close();
},
};
Expand Down
1 change: 1 addition & 0 deletions e2e/integration/counter-app/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import path from 'node:path';
import { type Build, type Dev, expect, test } from '@e2e/helper';
import type { Page } from 'playwright';

const PROJECT_DIR = path.resolve(
import.meta.dirname,
Expand Down
125 changes: 125 additions & 0 deletions e2e/integration/static-app/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import path from 'node:path';
import { type Build, type Dev, expect, test } from '@e2e/helper';
import type { Page } from 'playwright';

const PROJECT_DIR = path.resolve(
import.meta.dirname,
'../../../examples/static',
);

const setup = async (dev: Dev, build: Build, page: Page) => {
const rsbuild =
process.env.TEST_MODE === 'dev'
? await dev({ cwd: PROJECT_DIR })
: await build({ cwd: PROJECT_DIR, preview: true });

await page.goto(`http://localhost:${rsbuild.port}`);
return rsbuild;
};

test('should load the page and display the title', async ({
page,
dev,
build,
}) => {
await setup(dev, build, page);

await expect(page).toHaveTitle('Static RSC');

const heading = page.locator('h1');
await expect(heading).toBeVisible();
await expect(heading).toHaveText('This is an RSC!');

const links = page.locator('link[rel="stylesheet"]');
await expect(links).toHaveCount(1);
});

test('should display and interact with Counter component', async ({
page,
dev,
build,
}) => {
await setup(dev, build, page);

const counterButton = page.locator('button:has-text("Count:")');
await expect(counterButton).toBeVisible();
await expect(counterButton).toHaveText('Count: 0');

await counterButton.click();
await expect(counterButton).toHaveText('Count: 1');

await counterButton.click();
await expect(counterButton).toHaveText('Count: 2');

await counterButton.click();
await expect(counterButton).toHaveText('Count: 3');
});

test('should navigate to Other page via client-side navigation', async ({
page,
dev,
build,
}) => {
await setup(dev, build, page);

// Click the "Other" nav link
const otherLink = page.locator('nav a:has-text("Other")');
await expect(otherLink).toBeVisible();
await otherLink.click();

// Verify heading changes
const heading = page.locator('h1');
await expect(heading).toHaveText('This is another RSC!');

// Verify URL changed
await expect(page).toHaveURL(/\/other$/);
});

test('should apply CSS styles to current nav link', async ({
page,
dev,
build,
}) => {
await setup(dev, build, page);

const currentLink = page.locator('nav a[aria-current="page"]');
await expect(currentLink).toBeVisible();

const backgroundColor = await currentLink.evaluate((el) =>
window.getComputedStyle(el).getPropertyValue('background-color'),
);
expect(backgroundColor).toBe('rgb(0, 0, 0)');

const color = await currentLink.evaluate((el) =>
window.getComputedStyle(el).getPropertyValue('color'),
);
expect(color).toBe('rgb(255, 255, 255)');
});

test('should reset counter state on navigation', async ({
page,
dev,
build,
}) => {
await setup(dev, build, page);

// Increment counter
const counterButton = page.locator('button:has-text("Count:")');
await counterButton.click();
await counterButton.click();
await expect(counterButton).toHaveText('Count: 2');

// Navigate to Other page
const otherLink = page.locator('nav a:has-text("Other")');
await otherLink.click();
await expect(page.locator('h1')).toHaveText('This is another RSC!');

// Navigate back to Index page
const indexLink = page.locator('nav a:has-text("Index")');
await indexLink.click();
await expect(page.locator('h1')).toHaveText('This is an RSC!');

// Counter should be reset
const resetCounter = page.locator('button:has-text("Count:")');
await expect(resetCounter).toHaveText('Count: 0');
});
1 change: 1 addition & 0 deletions e2e/integration/todos-app/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import path from 'node:path';
import { type Build, type Dev, expect, test } from '@e2e/helper';
import type { Page } from 'playwright';

const PROJECT_DIR = path.resolve(
import.meta.dirname,
Expand Down
Loading
Loading