@rimori/playwright-testing 0.3.7 → 0.3.8-next.1

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.
@@ -1,4 +1,5 @@
1
1
  import { Browser, Page } from '@playwright/test';
2
+ import { Onboarding } from '../helpers/e2e/onboarding';
2
3
  interface RimoriE2ETestEnvironmentOptions {
3
4
  browser: Browser;
4
5
  pluginId: string;
@@ -10,12 +11,6 @@ interface Exercise {
10
11
  actionKey: string;
11
12
  parameters?: Record<string, unknown>;
12
13
  }
13
- export interface Onboarding {
14
- motivation_type?: string;
15
- preferred_genre?: string;
16
- target_country?: string;
17
- target_city?: string;
18
- }
19
14
  interface SetupOptions {
20
15
  onboarding?: Onboarding;
21
16
  exercises?: Array<Exercise>;
@@ -23,10 +23,10 @@ class RimoriE2ETestEnvironment {
23
23
  }
24
24
  async setup({ onboarding, exercises, studyPlan } = {}) {
25
25
  const onboardingData = {
26
- motivation_type: onboarding?.motivation_type ?? 'accomplishment',
27
- preferred_genre: onboarding?.preferred_genre ?? 'comedy',
26
+ learning_reason: onboarding?.learning_reason ?? 'work',
28
27
  target_country: onboarding?.target_country ?? 'SE',
29
28
  target_city: onboarding?.target_city ?? 'Malmö',
29
+ interests: onboarding?.interests ?? 'Travel, cooking, and music',
30
30
  };
31
31
  // Step 1: Create both test users (temp + persist) via API
32
32
  const { temp, persist } = await this.createTestUserViaApi();
@@ -1,8 +1,8 @@
1
1
  import { Page, Request } from '@playwright/test';
2
- import { UserInfo } from '@rimori/client/dist/controller/SettingsController';
3
- import { MainPanelAction, Plugin } from '@rimori/client/dist/fromRimori/PluginTypes';
2
+ import { UserInfo } from '@rimori/client';
3
+ import { MainPanelAction, Plugin, SidebarAction } from '@rimori/client';
4
4
  import { PluginSettings } from './SettingsStateManager';
5
- import { EventPayload } from '@rimori/client/dist/fromRimori/EventBus';
5
+ import { EventPayload } from '@rimori/client';
6
6
  import { LanguageLevel } from '@rimori/client';
7
7
  interface RimoriTestEnvironmentOptions {
8
8
  page: Page;
@@ -215,9 +215,9 @@ export declare class RimoriTestEnvironment {
215
215
  /**
216
216
  * Triggers a side panel action event as the parent application would.
217
217
  * This simulates how rimori-main's SidebarPluginHandler responds to plugin's 'action.requestSidebar' events.
218
- * @param payload - The action payload containing plugin_id, action_key, and action parameters
218
+ * @param payload - The action payload containing text, action key, and optional args
219
219
  */
220
- triggerOnSidePanelAction: (payload: MainPanelAction) => Promise<void>;
220
+ triggerOnSidePanelAction: (payload: SidebarAction) => Promise<void>;
221
221
  /**
222
222
  * Triggers a main panel action event as the parent application would.
223
223
  * This simulates how rimori-main's MainPluginHandler uses EventBus.respond to respond
@@ -160,7 +160,7 @@ class RimoriTestEnvironment {
160
160
  /**
161
161
  * Triggers a side panel action event as the parent application would.
162
162
  * This simulates how rimori-main's SidebarPluginHandler responds to plugin's 'action.requestSidebar' events.
163
- * @param payload - The action payload containing plugin_id, action_key, and action parameters
163
+ * @param payload - The action payload containing text, action key, and optional args
164
164
  */
165
165
  triggerOnSidePanelAction: async (payload) => {
166
166
  if (!this.messageChannelSimulator) {
@@ -23,8 +23,8 @@ exports.DEFAULT_USER_INFO = {
23
23
  skill_level_speaking: 'Pre-A1',
24
24
  skill_level_listening: 'Pre-A1',
25
25
  skill_level_understanding: 'Pre-A1',
26
- goal_longterm: 'Learn Swedish',
27
- goal_weekly: 'Practice daily',
26
+ learning_reason: 'growth',
27
+ personal_interests: 'Travel and cooking',
28
28
  study_buddy: {
29
29
  id: 'buddy-1',
30
30
  name: 'Test Buddy',
@@ -33,9 +33,7 @@ exports.DEFAULT_USER_INFO = {
33
33
  voiceId: 'alloy',
34
34
  aiPersonality: 'friendly',
35
35
  },
36
- story_genre: 'fiction',
37
36
  study_duration: 30,
38
- motivation_type: 'career',
39
37
  onboarding_completed: true,
40
38
  context_menu_on_select: true,
41
39
  user_name: 'Test User',
@@ -1,3 +1,21 @@
1
1
  import { Page } from "@playwright/test";
2
- import { Onboarding } from "../../core/RimoriE2ETestEnvironment";
2
+ export interface Onboarding {
3
+ learning_reason?: keyof typeof learningReasonMap;
4
+ target_country?: string;
5
+ target_city?: string;
6
+ interests?: string;
7
+ }
8
+ declare const learningReasonMap: {
9
+ work: string;
10
+ relationship: string;
11
+ friends_family: string;
12
+ education: string;
13
+ moving: string;
14
+ culture_travel: string;
15
+ self_improvement: string;
16
+ citizenship: string;
17
+ other: string;
18
+ speaking: string;
19
+ };
3
20
  export declare function completeOnboarding(page: Page, onboarding: Required<Onboarding>, e2ePluginId?: string): Promise<void>;
21
+ export {};
@@ -2,6 +2,18 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.completeOnboarding = completeOnboarding;
4
4
  const test_1 = require("@playwright/test");
5
+ const learningReasonMap = {
6
+ work: 'For my job',
7
+ relationship: 'For my relationship',
8
+ friends_family: 'For friends and family',
9
+ education: 'For education',
10
+ moving: 'Moving or living abroad',
11
+ culture_travel: 'For culture and travel',
12
+ self_improvement: 'Self-improvement',
13
+ citizenship: 'For citizenship or residency',
14
+ other: 'Other reason',
15
+ speaking: 'What is your main motivation to learn Swedish?',
16
+ };
5
17
  async function completeOnboarding(page, onboarding, e2ePluginId) {
6
18
  console.log(`[E2E] Onboarding user`);
7
19
  console.log(`[E2E] E2E plugin ID: ${e2ePluginId}`);
@@ -12,46 +24,44 @@ async function completeOnboarding(page, onboarding, e2ePluginId) {
12
24
  page.setDefaultNavigationTimeout(60000);
13
25
  // Ensure we're on onboarding page
14
26
  await (0, test_1.expect)(page).toHaveURL(/\/onboarding/);
15
- // Step 1: Purpose/Long-term goal
16
- const goalInput = page.locator('textarea, input[type="text"]');
17
- await goalInput.waitFor({ state: 'visible' });
18
- await goalInput.click();
19
- await goalInput.fill("test goal");
20
- const continueButton = page.getByRole('button', { name: /continue/i });
21
- await (0, test_1.expect)(continueButton).toBeEnabled({ timeout: 10000 });
22
- await continueButton.click();
23
- // Step 2: Motivation type (auto-advances after selection)
24
- // Wait for the motivation step heading to appear
25
- const motivationHeading = page.getByText('What motivates you most?');
26
- await (0, test_1.expect)(motivationHeading).toBeVisible({ timeout: 10000 });
27
- const motivationOption = page.locator('label').filter({ hasText: '🏆Progress & Accomplishment' });
28
- await (0, test_1.expect)(motivationOption).toBeVisible({ timeout: 10000 });
29
- await motivationOption.click();
30
- // Step 3: Genre preference (auto-advances after selection)
31
- // Wait for the genre step heading to appear
32
- const genreHeading = page.getByText('What kind of stories do you like most?');
33
- await (0, test_1.expect)(genreHeading).toBeVisible({ timeout: 10000 });
34
- const genreOption = page.locator('label').filter({ hasText: 'Comedy' });
35
- await (0, test_1.expect)(genreOption).toBeVisible({ timeout: 10000 });
36
- await genreOption.click();
37
- // Step 4: Location
38
- // Wait for the location step to appear
27
+ // Step 1: Learning Reason (radio select, auto-advances after selection)
28
+ const learningReasonOption = page.getByText(learningReasonMap[onboarding.learning_reason]);
29
+ await (0, test_1.expect)(learningReasonOption).toBeVisible({ timeout: 10000 });
30
+ await learningReasonOption.click();
31
+ // Step 2: Interests (textarea with continue button)
32
+ await page.waitForTimeout(1000);
33
+ const interestsTextarea = page.locator('textarea');
34
+ await (0, test_1.expect)(interestsTextarea).toBeVisible({ timeout: 10000 });
35
+ await interestsTextarea.click();
36
+ await interestsTextarea.fill(onboarding.interests);
37
+ const interestsContinue = page.getByRole('button', { name: /continue/i });
38
+ await (0, test_1.expect)(interestsContinue).toBeEnabled({ timeout: 10000 });
39
+ await interestsContinue.click();
40
+ // Step 3: Location
39
41
  const countrySelect = page.getByLabel('Country');
40
42
  await (0, test_1.expect)(countrySelect).toBeVisible({ timeout: 10000 });
41
- await countrySelect.selectOption('SE');
42
- await page.getByLabel('City (optional)').selectOption('Malmö');
43
+ await countrySelect.selectOption(onboarding.target_country);
44
+ await page.getByLabel('City (optional)').selectOption(onboarding.target_city);
43
45
  await page.getByRole('button', { name: 'Continue' }).click();
46
+ // Step 4: Study Buddy (card select, auto-advances after selection)
47
+ // Wait for study buddy step and click the first buddy card
48
+ await page.waitForTimeout(1000);
49
+ const buddyCard = page
50
+ .locator('button')
51
+ .filter({ has: page.locator('img') })
52
+ .first();
53
+ await (0, test_1.expect)(buddyCard).toBeVisible({ timeout: 10000 });
54
+ await buddyCard.click();
44
55
  // Step 5: Wait for setup completion
45
56
  await (0, test_1.expect)(page.getByRole('heading', { name: 'Almost there!' })).toBeVisible({ timeout: 10000 });
46
57
  await page.waitForURL('**/dashboard', { timeout: 120000 });
47
- // await page.screenshot({ path: path.join(process.cwd(), 'playwright/dashboard.png') });
48
58
  await (0, test_1.expect)(page.getByRole('heading', { name: "Today's Mission" })).toBeVisible({ timeout: 30000 });
49
59
  await (0, test_1.expect)(page.getByRole('button', { name: 'Grammar', exact: true })).toBeVisible({ timeout: 60000 });
50
60
  await (0, test_1.expect)(page.getByRole('heading', { name: 'Getting Started: Create your first study plan' })).toBeVisible({
51
61
  timeout: 60000,
52
62
  });
53
63
  await (0, test_1.expect)(page.getByText('Train your first flashcard deck', { exact: true })).toBeVisible({ timeout: 200000 });
54
- await (0, test_1.expect)(page.locator('iframe').contentFrame().getByRole('button', { name: 'Back to Plugins' })).toBeVisible({
64
+ await (0, test_1.expect)(page.locator('iframe').contentFrame().getByText('Getting Started', { exact: true })).toBeVisible({
55
65
  timeout: 250000,
56
66
  });
57
67
  }
@@ -67,8 +67,6 @@ test_1.test.describe('Demo Plugin', () => {
67
67
  (0, test_1.test)('translates via side panel action event', async ({ page }) => {
68
68
  // Set up the listener BEFORE navigating so it's ready when the plugin calls onSidePanelAction
69
69
  await env.event.triggerOnSidePanelAction({
70
- plugin_id: pluginId,
71
- action_key: 'translate',
72
70
  action: 'translate',
73
71
  text: 'tree',
74
72
  });
@@ -82,8 +80,6 @@ test_1.test.describe('Demo Plugin', () => {
82
80
  (0, test_1.test)('translates and resets the translator', async ({ page }) => {
83
81
  // Set up the listener BEFORE navigating so it's ready when the plugin calls onSidePanelAction
84
82
  await env.event.triggerOnSidePanelAction({
85
- plugin_id: pluginId,
86
- action_key: 'translate',
87
83
  action: 'translate',
88
84
  text: 'tree',
89
85
  });
@@ -105,8 +101,6 @@ test_1.test.describe('Demo Plugin', () => {
105
101
  await env.ai.mockGetSteamedText('This is a tree in Swedish: träd. It is an ett word.');
106
102
  // Set up the listener BEFORE navigating so it's ready when the plugin calls onSidePanelAction
107
103
  await env.event.triggerOnSidePanelAction({
108
- plugin_id: pluginId,
109
- action_key: 'translate',
110
104
  action: 'translate',
111
105
  text: 'tree',
112
106
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rimori/playwright-testing",
3
- "version": "0.3.7",
3
+ "version": "0.3.8-next.1",
4
4
  "description": "Playwright testing utilities for Rimori plugins and workers",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -26,11 +26,11 @@
26
26
  },
27
27
  "peerDependencies": {
28
28
  "@playwright/test": "^1.40.0",
29
- "@rimori/client": "^2.5.13"
29
+ "@rimori/client": "2.5.17-next.0"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@playwright/test": "^1.40.0",
33
- "@rimori/client": "^2.5.13",
33
+ "@rimori/client": "2.5.17-next.0",
34
34
  "@types/node": "^20.12.7",
35
35
  "rimraf": "^5.0.7",
36
36
  "typescript": "^5.7.2"