Skip to content

Commit 5c37cd2

Browse files
authored
feat: file-system API (#5)
1 parent 12b877c commit 5c37cd2

File tree

4 files changed

+93
-2
lines changed

4 files changed

+93
-2
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
run: pnpm typecheck
4040

4141
- name: Install Playwright Dependencies
42-
run: pnpm exec playwright install chromium firefox --with-deps
42+
run: pnpm exec playwright install chromium firefox --with-deps --only-shell
4343

4444
- name: Test
4545
run: pnpm test
@@ -48,7 +48,7 @@ jobs:
4848
uses: actions/upload-artifact@v4
4949
if: failure()
5050
with:
51-
name: vitest-screenshots
51+
name: vitest-screenshots-${{ matrix.node-version }}
5252
path: test/__screenshots__
5353
retention-days: 30
5454

src/fixtures/webcontainer.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { commands } from "@vitest/browser/context";
22
import {
3+
type BufferEncoding,
34
type FileSystemTree,
45
WebContainer as WebContainerApi,
56
} from "@webcontainer/api";
@@ -50,6 +51,9 @@ export class WebContainer {
5051
async teardown() {
5152
await Promise.all(this._onExit.map((fn) => fn()));
5253

54+
// @ts-ignore -- internal
55+
await this._instance._instance.teardown();
56+
5357
this._instance.teardown();
5458
this._instancePromise = undefined;
5559
}
@@ -81,4 +85,28 @@ export class WebContainer {
8185

8286
return output.trim();
8387
}
88+
89+
async readFile(path: string, encoding: BufferEncoding = "utf8") {
90+
return this._instance.fs.readFile(path, encoding);
91+
}
92+
93+
async writeFile(path: string, data: string, encoding = "utf8") {
94+
return this._instance.fs.writeFile(path, data, { encoding });
95+
}
96+
97+
async rename(oldPath: string, newPath: string) {
98+
return this._instance.fs.rename(oldPath, newPath);
99+
}
100+
101+
async mkdir(path: string) {
102+
return this._instance.fs.mkdir(path);
103+
}
104+
105+
async readdir(path: string) {
106+
return this._instance.fs.readdir(path);
107+
}
108+
109+
async rm(path: string) {
110+
return this._instance.fs.rm(path);
111+
}
84112
}

test/file-system.test.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { expect } from "vitest";
2+
import { test } from "../src";
3+
4+
test("user can create files and folders into webcontainer", async ({
5+
webcontainer,
6+
}) => {
7+
await webcontainer.writeFile("/example", "Hello world");
8+
await webcontainer.mkdir("/folder");
9+
10+
await expect(webcontainer.readdir("/")).resolves.toStrictEqual([
11+
"example",
12+
"folder",
13+
]);
14+
await expect(webcontainer.readFile("/example")).resolves.toBe("Hello world");
15+
});
16+
17+
test("user can rename files and folders in webcontainer", async ({
18+
webcontainer,
19+
}) => {
20+
await webcontainer.writeFile("/example", "Hello world");
21+
await webcontainer.mkdir("/folder");
22+
23+
await webcontainer.rename("/example", "/example-2");
24+
await webcontainer.rename("/folder", "/folder-2");
25+
26+
await expect(webcontainer.readdir("/")).resolves.toStrictEqual([
27+
"example-2",
28+
"folder-2",
29+
]);
30+
});
31+
32+
test("user can remove files from webcontainer", async ({ webcontainer }) => {
33+
await webcontainer.writeFile("/first", "1");
34+
await webcontainer.writeFile("/second", "2");
35+
await webcontainer.writeFile("/third", "3");
36+
37+
await webcontainer.rm("/second");
38+
await expect(webcontainer.readdir("/")).resolves.toStrictEqual([
39+
"first",
40+
"third",
41+
]);
42+
});

test/preview.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,24 @@ test("user can see server output in preview", async ({
1111

1212
await preview.getByRole("heading", { level: 1, name: "Hello Vite!" });
1313
});
14+
15+
test("user can see HMR changes in preview", async ({
16+
webcontainer,
17+
preview,
18+
}) => {
19+
await webcontainer.mount("test/fixtures/starter-vite");
20+
21+
await webcontainer.runCommand("npm", ["install"]);
22+
void webcontainer.runCommand("npm", ["run", "dev"]);
23+
24+
await preview.getByRole("heading", { level: 1, name: "Hello Vite!" });
25+
26+
const content = await webcontainer.readFile("/src/main.js");
27+
28+
await webcontainer.writeFile(
29+
"/src/main.js",
30+
content.replace("Hello Vite!", "Modified title!"),
31+
);
32+
33+
await preview.getByRole("heading", { level: 1, name: "Modified title!" });
34+
});

0 commit comments

Comments
 (0)