@@ -19,11 +19,15 @@ import { createRoot } from 'react-dom/client';
19
19
import { Button , TabItem } from './tabItem.js' ;
20
20
import type { TabInfo } from './tabItem.js' ;
21
21
22
- type StatusType = 'connected' | 'error' | 'connecting' ;
22
+ type Status =
23
+ | { type : 'connecting' ; message : string }
24
+ | { type : 'connected' ; message : string }
25
+ | { type : 'error' ; message : string }
26
+ | { type : 'error' ; versionMismatch : { pwMcpVersion : string ; extensionVersion : string } } ;
23
27
24
28
const ConnectApp : React . FC = ( ) => {
25
29
const [ tabs , setTabs ] = useState < TabInfo [ ] > ( [ ] ) ;
26
- const [ status , setStatus ] = useState < { type : StatusType ; message : string } | null > ( null ) ;
30
+ const [ status , setStatus ] = useState < Status | null > ( null ) ;
27
31
const [ showButtons , setShowButtons ] = useState ( true ) ;
28
32
const [ showTabList , setShowTabList ] = useState ( true ) ;
29
33
const [ clientInfo , setClientInfo ] = useState ( 'unknown' ) ;
@@ -54,7 +58,22 @@ const ConnectApp: React.FC = () => {
54
58
return ;
55
59
}
56
60
57
- void connectToMCPRelay ( relayUrl , params . get ( 'pwMcpVersion' ) ) ;
61
+ const pwMcpVersion = params . get ( 'pwMcpVersion' ) ;
62
+ const extensionVersion = chrome . runtime . getManifest ( ) . version ;
63
+ if ( pwMcpVersion !== extensionVersion ) {
64
+ setShowButtons ( false ) ;
65
+ setShowTabList ( false ) ;
66
+ setStatus ( {
67
+ type : 'error' ,
68
+ versionMismatch : {
69
+ pwMcpVersion : pwMcpVersion || 'unknown' ,
70
+ extensionVersion
71
+ }
72
+ } ) ;
73
+ return ;
74
+ }
75
+
76
+ void connectToMCPRelay ( relayUrl ) ;
58
77
void loadTabs ( ) ;
59
78
} , [ ] ) ;
60
79
@@ -64,8 +83,9 @@ const ConnectApp: React.FC = () => {
64
83
setStatus ( { type : 'error' , message } ) ;
65
84
} , [ ] ) ;
66
85
67
- const connectToMCPRelay = useCallback ( async ( mcpRelayUrl : string , pwMcpVersion : string | null ) => {
68
- const response = await chrome . runtime . sendMessage ( { type : 'connectToMCPRelay' , mcpRelayUrl, pwMcpVersion } ) ;
86
+ const connectToMCPRelay = useCallback ( async ( mcpRelayUrl : string ) => {
87
+
88
+ const response = await chrome . runtime . sendMessage ( { type : 'connectToMCPRelay' , mcpRelayUrl } ) ;
69
89
if ( ! response . success )
70
90
handleReject ( response . error ) ;
71
91
} , [ handleReject ] ) ;
@@ -122,7 +142,7 @@ const ConnectApp: React.FC = () => {
122
142
< div className = 'content-wrapper' >
123
143
{ status && (
124
144
< div className = 'status-container' >
125
- < StatusBanner type = { status . type } message = { status . message } />
145
+ < StatusBanner status = { status } />
126
146
{ showButtons && (
127
147
< Button variant = 'reject' onClick = { ( ) => handleReject ( 'Connection rejected. This tab can be closed.' ) } >
128
148
Reject
@@ -156,8 +176,27 @@ const ConnectApp: React.FC = () => {
156
176
) ;
157
177
} ;
158
178
159
- const StatusBanner : React . FC < { type : StatusType ; message : string } > = ( { type, message } ) => {
160
- return < div className = { `status-banner ${ type } ` } > { message } </ div > ;
179
+ const VersionMismatchError : React . FC < { pwMcpVersion : string ; extensionVersion : string } > = ( { pwMcpVersion, extensionVersion } ) => {
180
+ const readmeUrl = 'https://github.com/microsoft/playwright-mcp/blob/main/extension/README.md' ;
181
+ return (
182
+ < div >
183
+ Incompatible Playwright MCP version: { pwMcpVersion } (extension version: { extensionVersion } ).
184
+ Please install the latest version of the extension.{ ' ' }
185
+ See < a href = { readmeUrl } target = '_blank' rel = 'noopener noreferrer' > installation instructions</ a > .
186
+ </ div >
187
+ ) ;
188
+ } ;
189
+
190
+ const StatusBanner : React . FC < { status : Status } > = ( { status } ) => {
191
+ return (
192
+ < div className = { `status-banner ${ status . type } ` } >
193
+ { 'versionMismatch' in status ? (
194
+ < VersionMismatchError pwMcpVersion = { status . versionMismatch . pwMcpVersion } extensionVersion = { status . versionMismatch . extensionVersion } />
195
+ ) : (
196
+ status . message
197
+ ) }
198
+ </ div >
199
+ ) ;
161
200
} ;
162
201
163
202
// Initialize the React app
0 commit comments