Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit229c7e4

Browse files
committed
Add terminal page tests
1 parentcb5ae98 commit229c7e4

File tree

11 files changed

+358
-83
lines changed

11 files changed

+358
-83
lines changed

‎agent/agent.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ func (a *agent) handleReconnectingPTY(ctx context.Context, rawID string, conn ne
486486
gofunc() {
487487
// When the context has been completed either:
488488
// 1. The timeout completed.
489-
// 2. The parent context wascancelled.
489+
// 2. The parent context wascanceled.
490490
<-ctx.Done()
491491
_=process.Kill()
492492
}()

‎site/jest.config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ module.exports = {
2828
testRegex:"(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$",
2929
testPathIgnorePatterns:["/node_modules/","/__tests__/fakes","/e2e/"],
3030
moduleDirectories:["node_modules","<rootDir>"],
31+
moduleNameMapper:{
32+
"\\.css$":"<rootDir>/src/testHelpers/styleMock.ts",
33+
},
3134
},
3235
{
3336
displayName:"lint",

‎site/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"react-router-dom":"6.3.0",
4343
"swr":"1.2.2",
4444
"xstate":"4.31.0",
45+
"xterm":"^4.18.0",
4546
"xterm-addon-fit":"^0.5.0",
4647
"xterm-addon-web-links":"^0.5.1",
4748
"xterm-addon-webgl":"^0.11.4",
@@ -84,8 +85,10 @@
8485
"eslint-plugin-react-hooks":"4.4.0",
8586
"html-webpack-plugin":"5.5.0",
8687
"jest":"27.5.1",
88+
"jest-canvas-mock":"^2.4.0",
8789
"jest-junit":"13.1.0",
8890
"jest-runner-eslint":"1.0.0",
91+
"jest-websocket-mock":"^2.3.0",
8992
"mini-css-extract-plugin":"2.6.0",
9093
"msw":"0.39.2",
9194
"prettier":"2.6.2",

‎site/src/api/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,13 @@ export const getOrganizations = async (): Promise<Types.Organization[]> => {
9090
returnresponse.data
9191
}
9292

93-
exportconstgetWorkspace=async(organizationID:string,workspaceName:string):Promise<Types.Workspace>=>{
93+
exportconstgetWorkspace=async(
94+
organizationID:string,
95+
username="me",
96+
workspaceName:string,
97+
):Promise<Types.Workspace>=>{
9498
constresponse=awaitaxios.get<Types.Workspace>(
95-
`/api/v2/organizations/${organizationID}/workspaces/me/${workspaceName}`,
99+
`/api/v2/organizations/${organizationID}/workspaces/${username}/${workspaceName}`,
96100
)
97101
returnresponse.data
98102
}
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
import{waitFor}from"@testing-library/react"
2+
importcryptofrom"crypto"
3+
import"jest-canvas-mock"
4+
importWSfrom"jest-websocket-mock"
5+
import{rest}from"msw"
6+
importReactfrom"react"
7+
import{Route,Routes}from"react-router-dom"
8+
import{TextDecoder,TextEncoder}from"util"
9+
import{ReconnectingPTYRequest}from"../../api/types"
10+
import{history,MockWorkspaceAgent,render}from"../../testHelpers"
11+
import{server}from"../../testHelpers/server"
12+
import{Language,TerminalPage}from"./TerminalPage"
13+
14+
Object.defineProperty(window,"matchMedia",{
15+
writable:true,
16+
value:jest.fn().mockImplementation((query)=>({
17+
matches:false,
18+
media:query,
19+
onchange:null,
20+
addListener:jest.fn(),// deprecated
21+
removeListener:jest.fn(),// deprecated
22+
addEventListener:jest.fn(),
23+
removeEventListener:jest.fn(),
24+
dispatchEvent:jest.fn(),
25+
})),
26+
})
27+
28+
Object.defineProperty(window,"crypto",{
29+
value:{
30+
randomUUID:()=>crypto.randomUUID(),
31+
},
32+
})
33+
34+
Object.defineProperty(window,"TextEncoder",{
35+
value:TextEncoder,
36+
})
37+
38+
constrenderTerminal=()=>{
39+
returnrender(
40+
<Routes>
41+
<Routepath="/:username/:workspace/terminal"element={<TerminalPagerenderer="dom"/>}/>
42+
</Routes>,
43+
)
44+
}
45+
46+
constexpectTerminalText=(container:HTMLElement,text:string)=>{
47+
returnwaitFor(()=>{
48+
constelements=container.getElementsByClassName("xterm-rows")
49+
if(elements.length<1){
50+
thrownewError("no xterm-rows")
51+
}
52+
constrow=elements[0]asHTMLDivElement
53+
if(!row.textContent){
54+
thrownewError("no text content")
55+
}
56+
expect(row.textContent).toContain(text)
57+
})
58+
}
59+
60+
describe("TerminalPage",()=>{
61+
beforeEach(()=>{
62+
history.push("/some-user/my-workspace/terminal")
63+
})
64+
65+
it("shows an error if fetching organizations fails",async()=>{
66+
// Given
67+
server.use(
68+
rest.get("/api/v2/users/me/organizations",async(req,res,ctx)=>{
69+
returnres(ctx.status(500),ctx.json({message:"nope"}))
70+
}),
71+
)
72+
73+
// When
74+
const{ container}=renderTerminal()
75+
76+
// Then
77+
awaitexpectTerminalText(container,Language.organizationsErrorMessagePrefix)
78+
})
79+
80+
it("shows an error if fetching workspace fails",async()=>{
81+
// Given
82+
server.use(
83+
rest.get("/api/v2/organizations/:organizationId/workspaces/:userName/:workspaceName",(req,res,ctx)=>{
84+
returnres(ctx.status(500),ctx.json({id:"workspace-id"}))
85+
}),
86+
)
87+
88+
// When
89+
const{ container}=renderTerminal()
90+
91+
// Then
92+
awaitexpectTerminalText(container,Language.workspaceErrorMessagePrefix)
93+
})
94+
95+
it("shows an error if fetching workspace agent fails",async()=>{
96+
// Given
97+
server.use(
98+
rest.get("/api/v2/workspacebuilds/:workspaceId/resources",(req,res,ctx)=>{
99+
returnres(ctx.status(500),ctx.json({message:"nope"}))
100+
}),
101+
)
102+
103+
// When
104+
const{ container}=renderTerminal()
105+
106+
// Then
107+
awaitexpectTerminalText(container,Language.workspaceAgentErrorMessagePrefix)
108+
})
109+
110+
it("shows an error if the websocket fails",async()=>{
111+
// Given
112+
server.use(
113+
rest.get("/api/v2/workspaceagents/:agentId/pty",(req,res,ctx)=>{
114+
returnres(ctx.status(500),ctx.json({}))
115+
}),
116+
)
117+
118+
// When
119+
const{ container}=renderTerminal()
120+
121+
// Then
122+
awaitexpectTerminalText(container,Language.websocketErrorMessagePrefix)
123+
})
124+
125+
it("renders data from the backend",async()=>{
126+
// Given
127+
constserver=newWS("ws://localhost/api/v2/workspaceagents/"+MockWorkspaceAgent.id+"/pty")
128+
consttext="something to render"
129+
130+
// When
131+
const{ container}=renderTerminal()
132+
133+
// Then
134+
awaitserver.connected
135+
server.send(text)
136+
awaitexpectTerminalText(container,text)
137+
server.close()
138+
})
139+
140+
it("resizes on connect",async()=>{
141+
// Given
142+
constserver=newWS("ws://localhost/api/v2/workspaceagents/"+MockWorkspaceAgent.id+"/pty")
143+
144+
// When
145+
renderTerminal()
146+
147+
// Then
148+
awaitserver.connected
149+
constmsg=awaitserver.nextMessage
150+
constreq:ReconnectingPTYRequest=JSON.parse(newTextDecoder().decode(msgasUint8Array))
151+
152+
expect(req.height).toBeGreaterThan(0)
153+
expect(req.width).toBeGreaterThan(0)
154+
server.close()
155+
})
156+
})

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp