sunpeak 0.8.8 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/sunpeak.js +4 -0
- package/dist/chatgpt/chatgpt-simulator.d.ts +1 -2
- package/dist/chatgpt/index.cjs +9 -0
- package/dist/chatgpt/index.cjs.map +1 -0
- package/dist/chatgpt/index.d.ts +3 -1
- package/dist/chatgpt/index.js +9 -0
- package/dist/chatgpt/index.js.map +1 -0
- package/dist/chatgpt/simulator-url.d.ts +127 -0
- package/dist/index.cjs +39 -8448
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +58 -8466
- package/dist/index.js.map +1 -1
- package/dist/mcp/entry.cjs +2 -1
- package/dist/mcp/entry.cjs.map +1 -1
- package/dist/mcp/entry.js +2 -1
- package/dist/mcp/entry.js.map +1 -1
- package/dist/mcp/index.cjs +1 -1
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.js +1 -1
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/types.d.ts +3 -9
- package/dist/{server-DVmTC-SF.js → server-310A1k9o.js} +2 -2
- package/dist/{server-DVmTC-SF.js.map → server-310A1k9o.js.map} +1 -1
- package/dist/{server-B9YgCQdS.cjs → server-CSybLAYo.cjs} +2 -2
- package/dist/{server-B9YgCQdS.cjs.map → server-CSybLAYo.cjs.map} +1 -1
- package/dist/simulator-url-CG8lAAC3.cjs +8545 -0
- package/dist/simulator-url-CG8lAAC3.cjs.map +1 -0
- package/dist/simulator-url-CexnaL-e.js +8529 -0
- package/dist/simulator-url-CexnaL-e.js.map +1 -0
- package/dist/style.css +5858 -5843
- package/dist/types/simulation.d.ts +6 -32
- package/package.json +7 -3
- package/template/.sunpeak/dev.tsx +12 -7
- package/template/dist/albums.js +1 -1
- package/template/dist/albums.json +1 -1
- package/template/dist/carousel.js +1 -1
- package/template/dist/carousel.json +1 -1
- package/template/dist/map.js +1 -1
- package/template/dist/map.json +1 -1
- package/template/dist/review.js +2 -2
- package/template/dist/review.json +1 -1
- package/template/node_modules/.bin/playwright +21 -0
- package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_SegmentedControl.js +4 -4
- package/template/node_modules/.vite/deps/@openai_apps-sdk-ui_components_Select.js +6 -6
- package/template/node_modules/.vite/deps/_metadata.json +28 -28
- package/template/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/template/package.json +3 -1
- package/template/playwright.config.ts +26 -0
- package/template/src/resources/review-resource.test.tsx +2 -2
- package/template/src/resources/review-resource.tsx +6 -1
- package/template/src/simulations/albums-show-simulation.json +1 -1
- package/template/src/simulations/carousel-show-simulation.json +1 -1
- package/template/src/simulations/map-show-simulation.json +1 -1
- package/template/src/simulations/review-diff-simulation.json +1 -1
- package/template/src/simulations/review-post-simulation.json +1 -1
- package/template/src/simulations/review-purchase-simulation.json +1 -1
- package/template/test-results/.last-run.json +4 -0
- package/template/tests/e2e/albums.spec.ts +120 -0
- package/template/tests/e2e/carousel.spec.ts +127 -0
- package/template/tests/e2e/map.spec.ts +188 -0
- package/template/tests/e2e/review.spec.ts +245 -0
- package/template/vitest.config.ts +1 -0
- package/template/.sunpeak/vite-env.d.ts +0 -1
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
|
+
|
|
4
|
+
case `uname` in
|
|
5
|
+
*CYGWIN*|*MINGW*|*MSYS*)
|
|
6
|
+
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
+
basedir=`cygpath -w "$basedir"`
|
|
8
|
+
fi
|
|
9
|
+
;;
|
|
10
|
+
esac
|
|
11
|
+
|
|
12
|
+
if [ -z "$NODE_PATH" ]; then
|
|
13
|
+
export NODE_PATH="/home/runner/work/sunpeak/sunpeak/node_modules/.pnpm/@playwright+test@1.57.0/node_modules/@playwright/test/node_modules:/home/runner/work/sunpeak/sunpeak/node_modules/.pnpm/@playwright+test@1.57.0/node_modules/@playwright/node_modules:/home/runner/work/sunpeak/sunpeak/node_modules/.pnpm/@playwright+test@1.57.0/node_modules:/home/runner/work/sunpeak/sunpeak/node_modules/.pnpm/node_modules"
|
|
14
|
+
else
|
|
15
|
+
export NODE_PATH="/home/runner/work/sunpeak/sunpeak/node_modules/.pnpm/@playwright+test@1.57.0/node_modules/@playwright/test/node_modules:/home/runner/work/sunpeak/sunpeak/node_modules/.pnpm/@playwright+test@1.57.0/node_modules/@playwright/node_modules:/home/runner/work/sunpeak/sunpeak/node_modules/.pnpm/@playwright+test@1.57.0/node_modules:/home/runner/work/sunpeak/sunpeak/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
|
+
fi
|
|
17
|
+
if [ -x "$basedir/node" ]; then
|
|
18
|
+
exec "$basedir/node" "$basedir/../@playwright/test/cli.js" "$@"
|
|
19
|
+
else
|
|
20
|
+
exec node "$basedir/../@playwright/test/cli.js" "$@"
|
|
21
|
+
fi
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
dist_exports4 as dist_exports
|
|
3
|
+
} from "./chunk-TSEQUROC.js";
|
|
4
|
+
import "./chunk-XZTIOEPG.js";
|
|
1
5
|
import {
|
|
2
6
|
useResizeObserver
|
|
3
7
|
} from "./chunk-JAGHY6H6.js";
|
|
@@ -6,10 +10,6 @@ import {
|
|
|
6
10
|
waitForAnimationFrame
|
|
7
11
|
} from "./chunk-DYQDWJMS.js";
|
|
8
12
|
import "./chunk-EGRHWZRV.js";
|
|
9
|
-
import {
|
|
10
|
-
dist_exports4 as dist_exports
|
|
11
|
-
} from "./chunk-TSEQUROC.js";
|
|
12
|
-
import "./chunk-XZTIOEPG.js";
|
|
13
13
|
import {
|
|
14
14
|
clsx_default
|
|
15
15
|
} from "./chunk-CNYJBM5F.js";
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Input
|
|
3
3
|
} from "./chunk-2DZGWGIP.js";
|
|
4
|
+
import {
|
|
5
|
+
dist_exports,
|
|
6
|
+
dist_exports3 as dist_exports2,
|
|
7
|
+
dist_exports5 as dist_exports3
|
|
8
|
+
} from "./chunk-TSEQUROC.js";
|
|
9
|
+
import "./chunk-XZTIOEPG.js";
|
|
4
10
|
import {
|
|
5
11
|
Button,
|
|
6
12
|
LoadingIndicator,
|
|
@@ -19,12 +25,6 @@ import {
|
|
|
19
25
|
waitForAnimationFrame
|
|
20
26
|
} from "./chunk-DYQDWJMS.js";
|
|
21
27
|
import "./chunk-EGRHWZRV.js";
|
|
22
|
-
import {
|
|
23
|
-
dist_exports,
|
|
24
|
-
dist_exports3 as dist_exports2,
|
|
25
|
-
dist_exports5 as dist_exports3
|
|
26
|
-
} from "./chunk-TSEQUROC.js";
|
|
27
|
-
import "./chunk-XZTIOEPG.js";
|
|
28
28
|
import {
|
|
29
29
|
clsx_default
|
|
30
30
|
} from "./chunk-CNYJBM5F.js";
|
|
@@ -1,121 +1,121 @@
|
|
|
1
1
|
{
|
|
2
|
-
"hash": "
|
|
2
|
+
"hash": "b74c9763",
|
|
3
3
|
"configHash": "f56e5903",
|
|
4
|
-
"lockfileHash": "
|
|
5
|
-
"browserHash": "
|
|
4
|
+
"lockfileHash": "8ed69ad2",
|
|
5
|
+
"browserHash": "238bb651",
|
|
6
6
|
"optimized": {
|
|
7
7
|
"react": {
|
|
8
8
|
"src": "../../../../node_modules/.pnpm/react@19.2.3/node_modules/react/index.js",
|
|
9
9
|
"file": "react.js",
|
|
10
|
-
"fileHash": "
|
|
10
|
+
"fileHash": "9f8922cb",
|
|
11
11
|
"needsInterop": true
|
|
12
12
|
},
|
|
13
13
|
"react-dom": {
|
|
14
14
|
"src": "../../../../node_modules/.pnpm/react-dom@19.2.3_react@19.2.3/node_modules/react-dom/index.js",
|
|
15
15
|
"file": "react-dom.js",
|
|
16
|
-
"fileHash": "
|
|
16
|
+
"fileHash": "b39e5f22",
|
|
17
17
|
"needsInterop": true
|
|
18
18
|
},
|
|
19
19
|
"react/jsx-dev-runtime": {
|
|
20
20
|
"src": "../../../../node_modules/.pnpm/react@19.2.3/node_modules/react/jsx-dev-runtime.js",
|
|
21
21
|
"file": "react_jsx-dev-runtime.js",
|
|
22
|
-
"fileHash": "
|
|
22
|
+
"fileHash": "98b0fafe",
|
|
23
23
|
"needsInterop": true
|
|
24
24
|
},
|
|
25
25
|
"react/jsx-runtime": {
|
|
26
26
|
"src": "../../../../node_modules/.pnpm/react@19.2.3/node_modules/react/jsx-runtime.js",
|
|
27
27
|
"file": "react_jsx-runtime.js",
|
|
28
|
-
"fileHash": "
|
|
28
|
+
"fileHash": "589dec17",
|
|
29
29
|
"needsInterop": true
|
|
30
30
|
},
|
|
31
31
|
"@openai/apps-sdk-ui/components/Avatar": {
|
|
32
32
|
"src": "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.7__@types+react@19._90324f97b7190ccfdbe40a9e8bef3385/node_modules/@openai/apps-sdk-ui/dist/es/components/Avatar/index.js",
|
|
33
33
|
"file": "@openai_apps-sdk-ui_components_Avatar.js",
|
|
34
|
-
"fileHash": "
|
|
34
|
+
"fileHash": "e1ca40fe",
|
|
35
35
|
"needsInterop": false
|
|
36
36
|
},
|
|
37
37
|
"@openai/apps-sdk-ui/components/Button": {
|
|
38
38
|
"src": "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.7__@types+react@19._90324f97b7190ccfdbe40a9e8bef3385/node_modules/@openai/apps-sdk-ui/dist/es/components/Button/index.js",
|
|
39
39
|
"file": "@openai_apps-sdk-ui_components_Button.js",
|
|
40
|
-
"fileHash": "
|
|
40
|
+
"fileHash": "4566ca48",
|
|
41
41
|
"needsInterop": false
|
|
42
42
|
},
|
|
43
43
|
"@openai/apps-sdk-ui/components/Checkbox": {
|
|
44
44
|
"src": "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.7__@types+react@19._90324f97b7190ccfdbe40a9e8bef3385/node_modules/@openai/apps-sdk-ui/dist/es/components/Checkbox/index.js",
|
|
45
45
|
"file": "@openai_apps-sdk-ui_components_Checkbox.js",
|
|
46
|
-
"fileHash": "
|
|
46
|
+
"fileHash": "b2edde35",
|
|
47
47
|
"needsInterop": false
|
|
48
48
|
},
|
|
49
49
|
"@openai/apps-sdk-ui/components/Icon": {
|
|
50
50
|
"src": "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.7__@types+react@19._90324f97b7190ccfdbe40a9e8bef3385/node_modules/@openai/apps-sdk-ui/dist/es/components/Icon/index.js",
|
|
51
51
|
"file": "@openai_apps-sdk-ui_components_Icon.js",
|
|
52
|
-
"fileHash": "
|
|
52
|
+
"fileHash": "e62f20ec",
|
|
53
53
|
"needsInterop": false
|
|
54
54
|
},
|
|
55
55
|
"@openai/apps-sdk-ui/components/Input": {
|
|
56
56
|
"src": "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.7__@types+react@19._90324f97b7190ccfdbe40a9e8bef3385/node_modules/@openai/apps-sdk-ui/dist/es/components/Input/index.js",
|
|
57
57
|
"file": "@openai_apps-sdk-ui_components_Input.js",
|
|
58
|
-
"fileHash": "
|
|
58
|
+
"fileHash": "0204cb80",
|
|
59
59
|
"needsInterop": false
|
|
60
60
|
},
|
|
61
61
|
"@openai/apps-sdk-ui/components/SegmentedControl": {
|
|
62
62
|
"src": "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.7__@types+react@19._90324f97b7190ccfdbe40a9e8bef3385/node_modules/@openai/apps-sdk-ui/dist/es/components/SegmentedControl/index.js",
|
|
63
63
|
"file": "@openai_apps-sdk-ui_components_SegmentedControl.js",
|
|
64
|
-
"fileHash": "
|
|
64
|
+
"fileHash": "7bf18eee",
|
|
65
65
|
"needsInterop": false
|
|
66
66
|
},
|
|
67
67
|
"@openai/apps-sdk-ui/components/Select": {
|
|
68
68
|
"src": "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.7__@types+react@19._90324f97b7190ccfdbe40a9e8bef3385/node_modules/@openai/apps-sdk-ui/dist/es/components/Select/index.js",
|
|
69
69
|
"file": "@openai_apps-sdk-ui_components_Select.js",
|
|
70
|
-
"fileHash": "
|
|
70
|
+
"fileHash": "79ea3e4b",
|
|
71
71
|
"needsInterop": false
|
|
72
72
|
},
|
|
73
73
|
"@openai/apps-sdk-ui/components/Textarea": {
|
|
74
74
|
"src": "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.7__@types+react@19._90324f97b7190ccfdbe40a9e8bef3385/node_modules/@openai/apps-sdk-ui/dist/es/components/Textarea/index.js",
|
|
75
75
|
"file": "@openai_apps-sdk-ui_components_Textarea.js",
|
|
76
|
-
"fileHash": "
|
|
76
|
+
"fileHash": "44843a19",
|
|
77
77
|
"needsInterop": false
|
|
78
78
|
},
|
|
79
79
|
"@openai/apps-sdk-ui/theme": {
|
|
80
80
|
"src": "../../../../node_modules/.pnpm/@openai+apps-sdk-ui@0.2.1_@types+react-dom@19.2.3_@types+react@19.2.7__@types+react@19._90324f97b7190ccfdbe40a9e8bef3385/node_modules/@openai/apps-sdk-ui/dist/es/lib/theme.js",
|
|
81
81
|
"file": "@openai_apps-sdk-ui_theme.js",
|
|
82
|
-
"fileHash": "
|
|
82
|
+
"fileHash": "e60dca1c",
|
|
83
83
|
"needsInterop": false
|
|
84
84
|
},
|
|
85
85
|
"clsx": {
|
|
86
86
|
"src": "../../../../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs",
|
|
87
87
|
"file": "clsx.js",
|
|
88
|
-
"fileHash": "
|
|
88
|
+
"fileHash": "f15d30c1",
|
|
89
89
|
"needsInterop": false
|
|
90
90
|
},
|
|
91
91
|
"embla-carousel-react": {
|
|
92
92
|
"src": "../../../../node_modules/.pnpm/embla-carousel-react@8.6.0_react@19.2.3/node_modules/embla-carousel-react/esm/embla-carousel-react.esm.js",
|
|
93
93
|
"file": "embla-carousel-react.js",
|
|
94
|
-
"fileHash": "
|
|
94
|
+
"fileHash": "6b3141d4",
|
|
95
95
|
"needsInterop": false
|
|
96
96
|
},
|
|
97
97
|
"embla-carousel-wheel-gestures": {
|
|
98
98
|
"src": "../../../../node_modules/.pnpm/embla-carousel-wheel-gestures@8.1.0_embla-carousel@8.6.0/node_modules/embla-carousel-wheel-gestures/dist/embla-carousel-wheel-gestures.esm.js",
|
|
99
99
|
"file": "embla-carousel-wheel-gestures.js",
|
|
100
|
-
"fileHash": "
|
|
100
|
+
"fileHash": "efa2153a",
|
|
101
101
|
"needsInterop": false
|
|
102
102
|
},
|
|
103
103
|
"mapbox-gl": {
|
|
104
104
|
"src": "../../../../node_modules/.pnpm/mapbox-gl@3.17.0/node_modules/mapbox-gl/dist/mapbox-gl.js",
|
|
105
105
|
"file": "mapbox-gl.js",
|
|
106
|
-
"fileHash": "
|
|
106
|
+
"fileHash": "2b20f694",
|
|
107
107
|
"needsInterop": true
|
|
108
108
|
},
|
|
109
109
|
"react-dom/client": {
|
|
110
110
|
"src": "../../../../node_modules/.pnpm/react-dom@19.2.3_react@19.2.3/node_modules/react-dom/client.js",
|
|
111
111
|
"file": "react-dom_client.js",
|
|
112
|
-
"fileHash": "
|
|
112
|
+
"fileHash": "5e9ee085",
|
|
113
113
|
"needsInterop": true
|
|
114
114
|
},
|
|
115
115
|
"tailwind-merge": {
|
|
116
116
|
"src": "../../../../node_modules/.pnpm/tailwind-merge@3.4.0/node_modules/tailwind-merge/dist/bundle-mjs.mjs",
|
|
117
117
|
"file": "tailwind-merge.js",
|
|
118
|
-
"fileHash": "
|
|
118
|
+
"fileHash": "487e9f49",
|
|
119
119
|
"needsInterop": false
|
|
120
120
|
}
|
|
121
121
|
},
|
|
@@ -123,6 +123,12 @@
|
|
|
123
123
|
"chunk-2DZGWGIP": {
|
|
124
124
|
"file": "chunk-2DZGWGIP.js"
|
|
125
125
|
},
|
|
126
|
+
"chunk-TSEQUROC": {
|
|
127
|
+
"file": "chunk-TSEQUROC.js"
|
|
128
|
+
},
|
|
129
|
+
"chunk-XZTIOEPG": {
|
|
130
|
+
"file": "chunk-XZTIOEPG.js"
|
|
131
|
+
},
|
|
126
132
|
"chunk-N6DVYEXK": {
|
|
127
133
|
"file": "chunk-N6DVYEXK.js"
|
|
128
134
|
},
|
|
@@ -138,12 +144,6 @@
|
|
|
138
144
|
"chunk-EGRHWZRV": {
|
|
139
145
|
"file": "chunk-EGRHWZRV.js"
|
|
140
146
|
},
|
|
141
|
-
"chunk-TSEQUROC": {
|
|
142
|
-
"file": "chunk-TSEQUROC.js"
|
|
143
|
-
},
|
|
144
|
-
"chunk-XZTIOEPG": {
|
|
145
|
-
"file": "chunk-XZTIOEPG.js"
|
|
146
|
-
},
|
|
147
147
|
"chunk-CNYJBM5F": {
|
|
148
148
|
"file": "chunk-CNYJBM5F.js"
|
|
149
149
|
},
|
package/template/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"4.0.16","results":[[":src/components/album/albums.test.tsx",{"duration":
|
|
1
|
+
{"version":"4.0.16","results":[[":src/components/album/albums.test.tsx",{"duration":337.9990579999999,"failed":false}],[":src/resources/carousel-resource.test.tsx",{"duration":249.7428500000001,"failed":false}],[":src/resources/review-resource.test.tsx",{"duration":532.4556819999998,"failed":false}],[":src/components/map/place-inspector.test.tsx",{"duration":402.02946900000006,"failed":false}],[":src/components/map/map-view.test.tsx",{"duration":91.84771499999988,"failed":false}],[":src/components/album/fullscreen-viewer.test.tsx",{"duration":254.4845110000001,"failed":false}],[":src/components/map/place-list.test.tsx",{"duration":157.57383200000004,"failed":false}],[":src/components/map/place-card.test.tsx",{"duration":353.70146399999976,"failed":false}],[":src/components/map/place-carousel.test.tsx",{"duration":461.7055280000002,"failed":false}],[":src/components/album/album-carousel.test.tsx",{"duration":96.31957500000021,"failed":false}],[":src/components/carousel/carousel.test.tsx",{"duration":88.95574399999987,"failed":false}],[":src/resources/map-resource.test.tsx",{"duration":294.10313500000007,"failed":false}],[":src/resources/albums-resource.test.tsx",{"duration":276.18517599999996,"failed":false}],[":src/components/album/film-strip.test.tsx",{"duration":478.3753600000002,"failed":false}],[":src/components/album/album-card.test.tsx",{"duration":350.313899,"failed":false}],[":src/components/carousel/card.test.tsx",{"duration":99.09871700000008,"failed":false}]]}
|
package/template/package.json
CHANGED
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
"dev": "sunpeak dev",
|
|
8
8
|
"build": "sunpeak build",
|
|
9
9
|
"mcp": "sunpeak mcp",
|
|
10
|
-
"test": "vitest run"
|
|
10
|
+
"test": "vitest run",
|
|
11
|
+
"test:e2e": "playwright test"
|
|
11
12
|
},
|
|
12
13
|
"dependencies": {
|
|
13
14
|
"@openai/apps-sdk-ui": "^0.2.1",
|
|
@@ -19,6 +20,7 @@
|
|
|
19
20
|
"tailwind-merge": "^3.4.0"
|
|
20
21
|
},
|
|
21
22
|
"devDependencies": {
|
|
23
|
+
"@playwright/test": "^1.57.0",
|
|
22
24
|
"@tailwindcss/vite": "^4.1.18",
|
|
23
25
|
"@testing-library/jest-dom": "^6.9.1",
|
|
24
26
|
"@testing-library/react": "^16.3.1",
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { defineConfig, devices } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
testDir: './tests/e2e',
|
|
5
|
+
fullyParallel: true,
|
|
6
|
+
forbidOnly: !!process.env.CI,
|
|
7
|
+
retries: process.env.CI ? 2 : 0,
|
|
8
|
+
workers: process.env.CI ? 1 : undefined,
|
|
9
|
+
reporter: 'list',
|
|
10
|
+
use: {
|
|
11
|
+
baseURL: 'http://localhost:6776',
|
|
12
|
+
trace: 'on-first-retry',
|
|
13
|
+
},
|
|
14
|
+
projects: [
|
|
15
|
+
{
|
|
16
|
+
name: 'chromium',
|
|
17
|
+
use: { ...devices['Desktop Chrome'] },
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
webServer: {
|
|
21
|
+
command: 'PORT=6776 pnpm dev',
|
|
22
|
+
url: 'http://localhost:6776',
|
|
23
|
+
reuseExistingServer: !process.env.CI,
|
|
24
|
+
timeout: 10000,
|
|
25
|
+
},
|
|
26
|
+
});
|
|
@@ -107,12 +107,12 @@ describe('ReviewResource', () => {
|
|
|
107
107
|
expect(screen.getByText('Please review the following items')).toBeInTheDocument();
|
|
108
108
|
});
|
|
109
109
|
|
|
110
|
-
it('renders
|
|
110
|
+
it('renders loading when no sections', () => {
|
|
111
111
|
mockWidgetData = { title: 'Test', sections: [] };
|
|
112
112
|
|
|
113
113
|
render(<ReviewResource />);
|
|
114
114
|
|
|
115
|
-
expect(screen.getByText('
|
|
115
|
+
expect(screen.getByText('Loading...')).toBeInTheDocument();
|
|
116
116
|
});
|
|
117
117
|
|
|
118
118
|
it('has the correct displayName', () => {
|
|
@@ -425,7 +425,12 @@ export const ReviewResource = React.forwardRef<HTMLDivElement>((_props, ref) =>
|
|
|
425
425
|
|
|
426
426
|
{/* Sections */}
|
|
427
427
|
{sections.length === 0 ? (
|
|
428
|
-
|
|
428
|
+
// Note: Apps cannot distinguish between "still loading" and "empty response".
|
|
429
|
+
// We show a loading state as the optimistic assumption.
|
|
430
|
+
<div className="flex items-center justify-center gap-2 py-8 text-secondary">
|
|
431
|
+
<div className="w-4 h-4 border-2 border-current border-t-transparent rounded-full animate-spin" />
|
|
432
|
+
<span>Loading...</span>
|
|
433
|
+
</div>
|
|
429
434
|
) : (
|
|
430
435
|
sections.map((section, i) => <Section key={i} section={section} />)
|
|
431
436
|
)}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"openai/resultCanProduceWidget": true
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
|
-
"
|
|
16
|
+
"callToolResult": {
|
|
17
17
|
"structuredContent": {
|
|
18
18
|
"title": "Refactor Authentication Module",
|
|
19
19
|
"description": "The following changes will update the authentication system to use JWT tokens instead of session-based auth.",
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { test, expect } from '@playwright/test';
|
|
2
|
+
import { createSimulatorUrl } from 'sunpeak/chatgpt';
|
|
3
|
+
|
|
4
|
+
test.describe('Albums Resource', () => {
|
|
5
|
+
test.describe('Light Mode', () => {
|
|
6
|
+
test('should render album cards with correct styles', async ({ page }) => {
|
|
7
|
+
await page.goto(createSimulatorUrl({ simulation: 'albums-show', theme: 'light' }));
|
|
8
|
+
|
|
9
|
+
const albumCard = page.locator('button:has-text("Summer Slice")');
|
|
10
|
+
await expect(albumCard).toBeVisible();
|
|
11
|
+
|
|
12
|
+
// Verify album card unique styles
|
|
13
|
+
const styles = await albumCard.evaluate((el) => {
|
|
14
|
+
const computed = window.getComputedStyle(el);
|
|
15
|
+
return {
|
|
16
|
+
cursor: computed.cursor,
|
|
17
|
+
borderRadius: computed.borderRadius,
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
expect(styles.cursor).toBe('pointer');
|
|
22
|
+
expect(styles.borderRadius).toBe('12px'); // rounded-xl
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test('should have album image with correct aspect ratio', async ({ page }) => {
|
|
26
|
+
await page.goto(createSimulatorUrl({ simulation: 'albums-show', theme: 'light' }));
|
|
27
|
+
|
|
28
|
+
const albumImage = page.locator('button:has-text("Summer Slice") img').first();
|
|
29
|
+
await expect(albumImage).toBeVisible();
|
|
30
|
+
|
|
31
|
+
// Verify aspect-[4/3] container
|
|
32
|
+
const imageContainer = page.locator('button:has-text("Summer Slice") .aspect-\\[4\\/3\\]');
|
|
33
|
+
await expect(imageContainer).toBeVisible();
|
|
34
|
+
|
|
35
|
+
const containerStyles = await imageContainer.evaluate((el) => {
|
|
36
|
+
const computed = window.getComputedStyle(el);
|
|
37
|
+
return {
|
|
38
|
+
borderRadius: computed.borderRadius,
|
|
39
|
+
overflow: computed.overflow,
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
expect(containerStyles.borderRadius).toBe('12px'); // rounded-xl
|
|
44
|
+
expect(containerStyles.overflow).toBe('hidden');
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test.describe('Dark Mode', () => {
|
|
49
|
+
test('should render album cards with correct styles', async ({ page }) => {
|
|
50
|
+
await page.goto(createSimulatorUrl({ simulation: 'albums-show', theme: 'dark' }));
|
|
51
|
+
|
|
52
|
+
const albumCard = page.locator('button:has-text("Summer Slice")');
|
|
53
|
+
await expect(albumCard).toBeVisible();
|
|
54
|
+
|
|
55
|
+
const styles = await albumCard.evaluate((el) => {
|
|
56
|
+
const computed = window.getComputedStyle(el);
|
|
57
|
+
return {
|
|
58
|
+
cursor: computed.cursor,
|
|
59
|
+
borderRadius: computed.borderRadius,
|
|
60
|
+
};
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
expect(styles.cursor).toBe('pointer');
|
|
64
|
+
expect(styles.borderRadius).toBe('12px'); // rounded-xl
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test('should have text with appropriate contrast', async ({ page }) => {
|
|
68
|
+
await page.goto(createSimulatorUrl({ simulation: 'albums-show', theme: 'dark' }));
|
|
69
|
+
|
|
70
|
+
const albumTitle = page.locator('button:has-text("Summer Slice") .text-primary').first();
|
|
71
|
+
await expect(albumTitle).toBeVisible();
|
|
72
|
+
|
|
73
|
+
// In dark mode, text-primary should be light colored for contrast
|
|
74
|
+
const titleStyles = await albumTitle.evaluate((el) => {
|
|
75
|
+
const computed = window.getComputedStyle(el);
|
|
76
|
+
return {
|
|
77
|
+
color: computed.color,
|
|
78
|
+
};
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Verify the text color exists (should be a light color in dark mode)
|
|
82
|
+
expect(titleStyles.color).toBeTruthy();
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test.describe('Fullscreen Mode', () => {
|
|
87
|
+
test('should render correctly in fullscreen displayMode', async ({ page }) => {
|
|
88
|
+
await page.goto(
|
|
89
|
+
createSimulatorUrl({ simulation: 'albums-show', theme: 'light', displayMode: 'fullscreen' })
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
// Wait for content to load
|
|
93
|
+
await page.waitForLoadState('networkidle');
|
|
94
|
+
|
|
95
|
+
// The root container should be present
|
|
96
|
+
const root = page.locator('#root');
|
|
97
|
+
await expect(root).not.toBeEmpty();
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test('should maintain album card styles in fullscreen', async ({ page }) => {
|
|
101
|
+
await page.goto(
|
|
102
|
+
createSimulatorUrl({ simulation: 'albums-show', theme: 'dark', displayMode: 'fullscreen' })
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
const albumCard = page.locator('button:has-text("Summer Slice")');
|
|
106
|
+
await expect(albumCard).toBeVisible();
|
|
107
|
+
|
|
108
|
+
const styles = await albumCard.evaluate((el) => {
|
|
109
|
+
const computed = window.getComputedStyle(el);
|
|
110
|
+
return {
|
|
111
|
+
cursor: computed.cursor,
|
|
112
|
+
borderRadius: computed.borderRadius,
|
|
113
|
+
};
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
expect(styles.cursor).toBe('pointer');
|
|
117
|
+
expect(styles.borderRadius).toBe('12px');
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
});
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { test, expect } from '@playwright/test';
|
|
2
|
+
import { createSimulatorUrl } from 'sunpeak/chatgpt';
|
|
3
|
+
|
|
4
|
+
test.describe('Carousel Resource', () => {
|
|
5
|
+
test.describe('Light Mode', () => {
|
|
6
|
+
test('should render carousel cards with correct styles', async ({ page }) => {
|
|
7
|
+
await page.goto(createSimulatorUrl({ simulation: 'carousel-show', theme: 'light' }));
|
|
8
|
+
|
|
9
|
+
// Wait for carousel to load
|
|
10
|
+
await page.waitForLoadState('networkidle');
|
|
11
|
+
|
|
12
|
+
// Find a card in the carousel
|
|
13
|
+
const card = page.locator('.rounded-2xl').first();
|
|
14
|
+
await expect(card).toBeVisible();
|
|
15
|
+
|
|
16
|
+
const styles = await card.evaluate((el) => {
|
|
17
|
+
const computed = window.getComputedStyle(el);
|
|
18
|
+
return {
|
|
19
|
+
borderRadius: computed.borderRadius,
|
|
20
|
+
cursor: computed.cursor,
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
expect(styles.borderRadius).toBe('16px'); // rounded-2xl
|
|
25
|
+
expect(styles.cursor).toBe('pointer');
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('should have card with border styling', async ({ page }) => {
|
|
29
|
+
await page.goto(createSimulatorUrl({ simulation: 'carousel-show', theme: 'light' }));
|
|
30
|
+
|
|
31
|
+
await page.waitForLoadState('networkidle');
|
|
32
|
+
|
|
33
|
+
// Cards have border-subtle styling
|
|
34
|
+
const card = page.locator('.rounded-2xl.border').first();
|
|
35
|
+
await expect(card).toBeVisible();
|
|
36
|
+
|
|
37
|
+
const styles = await card.evaluate((el) => {
|
|
38
|
+
const computed = window.getComputedStyle(el);
|
|
39
|
+
return {
|
|
40
|
+
borderWidth: computed.borderWidth,
|
|
41
|
+
borderStyle: computed.borderStyle,
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
expect(styles.borderWidth).toBe('1px');
|
|
46
|
+
expect(styles.borderStyle).toBe('solid');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('should have interactive buttons', async ({ page }) => {
|
|
50
|
+
await page.goto(createSimulatorUrl({ simulation: 'carousel-show', theme: 'light' }));
|
|
51
|
+
|
|
52
|
+
await page.waitForLoadState('networkidle');
|
|
53
|
+
|
|
54
|
+
// Find the Visit button (primary button)
|
|
55
|
+
const visitButton = page.locator('button:has-text("Visit")').first();
|
|
56
|
+
await expect(visitButton).toBeAttached();
|
|
57
|
+
|
|
58
|
+
const styles = await visitButton.evaluate((el) => {
|
|
59
|
+
const computed = window.getComputedStyle(el);
|
|
60
|
+
return {
|
|
61
|
+
cursor: computed.cursor,
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
expect(styles.cursor).toBe('pointer');
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test.describe('Dark Mode', () => {
|
|
70
|
+
test('should render carousel cards with correct styles', async ({ page }) => {
|
|
71
|
+
await page.goto(createSimulatorUrl({ simulation: 'carousel-show', theme: 'dark' }));
|
|
72
|
+
|
|
73
|
+
await page.waitForLoadState('networkidle');
|
|
74
|
+
|
|
75
|
+
const card = page.locator('.rounded-2xl').first();
|
|
76
|
+
await expect(card).toBeVisible();
|
|
77
|
+
|
|
78
|
+
const styles = await card.evaluate((el) => {
|
|
79
|
+
const computed = window.getComputedStyle(el);
|
|
80
|
+
return {
|
|
81
|
+
borderRadius: computed.borderRadius,
|
|
82
|
+
cursor: computed.cursor,
|
|
83
|
+
};
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
expect(styles.borderRadius).toBe('16px'); // rounded-2xl
|
|
87
|
+
expect(styles.cursor).toBe('pointer');
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test('should have appropriate background color for dark mode', async ({ page }) => {
|
|
91
|
+
await page.goto(createSimulatorUrl({ simulation: 'carousel-show', theme: 'dark' }));
|
|
92
|
+
|
|
93
|
+
await page.waitForLoadState('networkidle');
|
|
94
|
+
|
|
95
|
+
// Verify the card has a background color set
|
|
96
|
+
const card = page.locator('.rounded-2xl.bg-surface').first();
|
|
97
|
+
await expect(card).toBeVisible();
|
|
98
|
+
|
|
99
|
+
const styles = await card.evaluate((el) => {
|
|
100
|
+
const computed = window.getComputedStyle(el);
|
|
101
|
+
return {
|
|
102
|
+
backgroundColor: computed.backgroundColor,
|
|
103
|
+
};
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Background color should be set (not transparent)
|
|
107
|
+
expect(styles.backgroundColor).toBeTruthy();
|
|
108
|
+
expect(styles.backgroundColor).not.toBe('rgba(0, 0, 0, 0)');
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test('should load without console errors', async ({ page }) => {
|
|
112
|
+
const errors: string[] = [];
|
|
113
|
+
page.on('console', (msg) => {
|
|
114
|
+
if (msg.type() === 'error') {
|
|
115
|
+
errors.push(msg.text());
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
await page.goto(createSimulatorUrl({ simulation: 'carousel-show', theme: 'dark' }));
|
|
120
|
+
await page.waitForLoadState('networkidle');
|
|
121
|
+
|
|
122
|
+
expect(errors).toHaveLength(0);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
// Note: No fullscreen test for carousel as per requirements
|
|
127
|
+
});
|