@rimori/playwright-testing 0.3.0 → 0.3.1-next.0

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.
@@ -40,6 +40,16 @@ export declare class MessageChannelSimulator {
40
40
  * Registers a handler for events emitted from the plugin.
41
41
  */
42
42
  on(topic: string, handler: EventListener): () => void;
43
+ /**
44
+ * Registers a persistent auto-responder for a request/response topic.
45
+ * The responder will continue to respond to all requests with the given topic
46
+ * until explicitly removed.
47
+ *
48
+ * @param topic - The event topic to respond to
49
+ * @param responder - A function that returns the response data, or a value to return directly
50
+ * @returns A function to manually remove the responder
51
+ */
52
+ respond(topic: string, responder: AutoResponder | unknown): () => void;
43
53
  /**
44
54
  * Registers a one-time auto-responder for a request/response topic.
45
55
  * When a request with an eventId comes in for this topic, the responder will
@@ -139,6 +139,29 @@ class MessageChannelSimulator {
139
139
  }
140
140
  };
141
141
  }
142
+ /**
143
+ * Registers a persistent auto-responder for a request/response topic.
144
+ * The responder will continue to respond to all requests with the given topic
145
+ * until explicitly removed.
146
+ *
147
+ * @param topic - The event topic to respond to
148
+ * @param responder - A function that returns the response data, or a value to return directly
149
+ * @returns A function to manually remove the responder
150
+ */
151
+ respond(topic, responder) {
152
+ const wrappedResponder = (event) => {
153
+ // If responder is a function, call it with the event, otherwise return the value directly
154
+ if (typeof responder === 'function') {
155
+ return responder(event);
156
+ }
157
+ return responder;
158
+ };
159
+ this.autoResponders.set(topic, wrappedResponder);
160
+ // Return a function to manually remove the responder
161
+ return () => {
162
+ this.autoResponders.delete(topic);
163
+ };
164
+ }
142
165
  /**
143
166
  * Registers a one-time auto-responder for a request/response topic.
144
167
  * When a request with an eventId comes in for this topic, the responder will
@@ -150,11 +150,11 @@ export declare class RimoriTestEnvironment {
150
150
  */
151
151
  mockEmit: (topic: string, data: EventPayload, sender?: string) => Promise<void>;
152
152
  /**
153
- * Registers a one-time auto-responder for request/response style events.
153
+ * Registers a persistent auto-responder for request/response style events.
154
154
  *
155
155
  * When the plugin calls `plugin.event.request(topic, data)`, this registered responder
156
- * will automatically return the provided response value. The responder is automatically
157
- * removed after the first request, ensuring it only responds once.
156
+ * will automatically return the provided response value. The responder persists and
157
+ * will respond to multiple requests until manually removed.
158
158
  *
159
159
  * Example:
160
160
  * ```ts
@@ -164,12 +164,12 @@ export declare class RimoriTestEnvironment {
164
164
  * ]);
165
165
  *
166
166
  * // Now when the plugin calls: plugin.event.request('deck.requestOpenToday', {})
167
- * // It will receive the deck summaries array above
167
+ * // It will receive the deck summaries array above (can be called multiple times)
168
168
  * ```
169
169
  *
170
170
  * @param topic - The event topic to respond to (e.g., 'deck.requestOpenToday')
171
171
  * @param response - The response value to return, or a function that receives the event and returns the response
172
- * @returns A function to manually remove the responder before it's used
172
+ * @returns A function to manually remove the responder
173
173
  */
174
174
  mockRequest: (topic: string, response: unknown | ((event: unknown) => unknown)) => () => void;
175
175
  /**
@@ -227,7 +227,7 @@ export declare class RimoriTestEnvironment {
227
227
  mockGetSteamedText: (text: string, options?: MockOptions) => void;
228
228
  mockGetVoice: (values: Buffer, options?: MockOptions) => void;
229
229
  mockGetTextFromVoice: (text: string, options?: MockOptions) => void;
230
- mockGetObject: (value: unknown, options?: MockOptions) => void;
230
+ mockGetObject: (value: Record<string, unknown>, options?: MockOptions) => void;
231
231
  };
232
232
  /**
233
233
  * Helpers for tracking browser audio playback in tests.
@@ -90,11 +90,11 @@ class RimoriTestEnvironment {
90
90
  await this.messageChannelSimulator.emit(topic, data, sender);
91
91
  },
92
92
  /**
93
- * Registers a one-time auto-responder for request/response style events.
93
+ * Registers a persistent auto-responder for request/response style events.
94
94
  *
95
95
  * When the plugin calls `plugin.event.request(topic, data)`, this registered responder
96
- * will automatically return the provided response value. The responder is automatically
97
- * removed after the first request, ensuring it only responds once.
96
+ * will automatically return the provided response value. The responder persists and
97
+ * will respond to multiple requests until manually removed.
98
98
  *
99
99
  * Example:
100
100
  * ```ts
@@ -104,18 +104,18 @@ class RimoriTestEnvironment {
104
104
  * ]);
105
105
  *
106
106
  * // Now when the plugin calls: plugin.event.request('deck.requestOpenToday', {})
107
- * // It will receive the deck summaries array above
107
+ * // It will receive the deck summaries array above (can be called multiple times)
108
108
  * ```
109
109
  *
110
110
  * @param topic - The event topic to respond to (e.g., 'deck.requestOpenToday')
111
111
  * @param response - The response value to return, or a function that receives the event and returns the response
112
- * @returns A function to manually remove the responder before it's used
112
+ * @returns A function to manually remove the responder
113
113
  */
114
114
  mockRequest: (topic, response) => {
115
115
  if (!this.messageChannelSimulator) {
116
116
  throw new Error('MessageChannelSimulator not initialized. Call setup() first.');
117
117
  }
118
- return this.messageChannelSimulator.respondOnce(topic, response);
118
+ return this.messageChannelSimulator.respond(topic, response);
119
119
  },
120
120
  /**
121
121
  * Listen for events emitted by the plugin.
@@ -184,14 +184,10 @@ class RimoriTestEnvironment {
184
184
  const topic = `${this.pluginId}.action.requestMain`;
185
185
  // Store the payload in a closure so we can respond with it
186
186
  const actionPayload = payload;
187
- // Set up a one-time listener that responds when the plugin emits 'action.requestMain'
188
- // The handler receives the event object from the plugin
189
- const off = this.messageChannelSimulator.on(topic, async (event) => {
190
- // When plugin emits 'action.requestMain', respond with the MainPanelAction data
191
- // The sender is 'mainPanel' to match rimori-main's MainPluginHandler behavior
192
- await this.messageChannelSimulator.emit(topic, actionPayload, 'mainPanel');
193
- off(); // Remove listener after responding once (one-time response like EventBus.respond)
194
- });
187
+ // Register a persistent auto-responder (not respondOnce) because the plugin may
188
+ // emit this event multiple times during its lifecycle. Using respondOnce would
189
+ // only respond to the first request and ignore subsequent ones.
190
+ this.messageChannelSimulator.respond(topic, actionPayload);
195
191
  },
196
192
  };
197
193
  this.ai = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rimori/playwright-testing",
3
- "version": "0.3.0",
3
+ "version": "0.3.1-next.0",
4
4
  "description": "Playwright testing utilities for Rimori plugins and workers",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {