@chrryai/waffles 2.3.60 → 2.3.71

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/dist/index.d.mts CHANGED
@@ -17,14 +17,14 @@ declare class APIClient {
17
17
  dispose(): Promise<void>;
18
18
  }
19
19
 
20
- interface ScheduledJob {
21
- id?: string;
20
+ /**
21
+ * Tribe Schedule Fixture
22
+ * Matches tribeScheduleSchema from @chrryai/chrry/schemas/tribeScheduleSchema
23
+ */
24
+ type ScheduledJob = TribeScheduleInput;
25
+ interface TribeScheduleInput {
26
+ sessionId?: string;
22
27
  appId?: string;
23
- createPending?: boolean;
24
- name: string;
25
- scheduleType: string;
26
- jobType: string;
27
- frequency: "once" | "daily" | "weekly" | "custom";
28
28
  schedule: Array<{
29
29
  time: string;
30
30
  postType: string;
@@ -36,30 +36,23 @@ interface ScheduledJob {
36
36
  generateVideo?: boolean;
37
37
  fetchNews?: boolean;
38
38
  }>;
39
- timezone: string;
40
- startDate: Date;
41
- endDate?: Date;
39
+ frequency: "once" | "daily" | "weekly" | "custom";
40
+ startDate: string;
41
+ endDate?: string;
42
+ contentTemplate?: string;
43
+ contentRules?: {
44
+ tone?: string;
45
+ length?: string;
46
+ topics?: string[];
47
+ hashtags?: string[];
48
+ };
42
49
  totalCredits: number;
43
50
  totalPrice: number;
44
- contentTemplate?: string | null;
45
- contentRules?: Record<string, unknown>;
46
- creditsUsed?: number;
47
- status?: "draft" | "pending_payment" | "active" | "paused" | "completed" | "canceled";
48
- lastRunAt?: Date | null;
49
- nextRunAt?: Date | null;
50
- totalRuns?: number;
51
- successfulRuns?: number;
52
- failedRuns?: number;
53
- failureReason?: string | null;
54
- pendingPayment?: number | null;
55
- calendarEventId?: string | null;
56
- metadata?: Record<string, unknown>;
57
- createdOn?: Date;
58
- updatedOn?: Date;
51
+ timezone: string;
59
52
  }
60
53
  declare const scheduledJobFactory: {
61
- build(overrides?: Partial<ScheduledJob>): ScheduledJob;
62
- buildMany(count: number, overrides?: Partial<ScheduledJob>): ScheduledJob[];
54
+ build(overrides?: Partial<TribeScheduleInput>): TribeScheduleInput;
55
+ buildMany(count: number, overrides?: Partial<TribeScheduleInput>): TribeScheduleInput[];
63
56
  };
64
57
 
65
58
  type modelName = "chatGPT" | "claude" | "gemini" | "sushi" | "perplexity";
package/dist/index.d.ts CHANGED
@@ -17,14 +17,14 @@ declare class APIClient {
17
17
  dispose(): Promise<void>;
18
18
  }
19
19
 
20
- interface ScheduledJob {
21
- id?: string;
20
+ /**
21
+ * Tribe Schedule Fixture
22
+ * Matches tribeScheduleSchema from @chrryai/chrry/schemas/tribeScheduleSchema
23
+ */
24
+ type ScheduledJob = TribeScheduleInput;
25
+ interface TribeScheduleInput {
26
+ sessionId?: string;
22
27
  appId?: string;
23
- createPending?: boolean;
24
- name: string;
25
- scheduleType: string;
26
- jobType: string;
27
- frequency: "once" | "daily" | "weekly" | "custom";
28
28
  schedule: Array<{
29
29
  time: string;
30
30
  postType: string;
@@ -36,30 +36,23 @@ interface ScheduledJob {
36
36
  generateVideo?: boolean;
37
37
  fetchNews?: boolean;
38
38
  }>;
39
- timezone: string;
40
- startDate: Date;
41
- endDate?: Date;
39
+ frequency: "once" | "daily" | "weekly" | "custom";
40
+ startDate: string;
41
+ endDate?: string;
42
+ contentTemplate?: string;
43
+ contentRules?: {
44
+ tone?: string;
45
+ length?: string;
46
+ topics?: string[];
47
+ hashtags?: string[];
48
+ };
42
49
  totalCredits: number;
43
50
  totalPrice: number;
44
- contentTemplate?: string | null;
45
- contentRules?: Record<string, unknown>;
46
- creditsUsed?: number;
47
- status?: "draft" | "pending_payment" | "active" | "paused" | "completed" | "canceled";
48
- lastRunAt?: Date | null;
49
- nextRunAt?: Date | null;
50
- totalRuns?: number;
51
- successfulRuns?: number;
52
- failedRuns?: number;
53
- failureReason?: string | null;
54
- pendingPayment?: number | null;
55
- calendarEventId?: string | null;
56
- metadata?: Record<string, unknown>;
57
- createdOn?: Date;
58
- updatedOn?: Date;
51
+ timezone: string;
59
52
  }
60
53
  declare const scheduledJobFactory: {
61
- build(overrides?: Partial<ScheduledJob>): ScheduledJob;
62
- buildMany(count: number, overrides?: Partial<ScheduledJob>): ScheduledJob[];
54
+ build(overrides?: Partial<TribeScheduleInput>): TribeScheduleInput;
55
+ buildMany(count: number, overrides?: Partial<TribeScheduleInput>): TribeScheduleInput[];
63
56
  };
64
57
 
65
58
  type modelName = "chatGPT" | "claude" | "gemini" | "sushi" | "perplexity";
package/dist/index.js CHANGED
@@ -102,12 +102,11 @@ var APIClient = class {
102
102
  };
103
103
  var scheduledJobFactory = {
104
104
  build(overrides) {
105
+ const startDate = /* @__PURE__ */ new Date();
106
+ const endDate = new Date(startDate);
107
+ endDate.setDate(endDate.getDate() + 7);
105
108
  return {
106
- id: faker.faker.string.uuid(),
107
- createPending: true,
108
- name: faker.faker.lorem.words(3),
109
- scheduleType: "tribe",
110
- jobType: "post",
109
+ // Required fields per tribeScheduleSchema
111
110
  frequency: "daily",
112
111
  schedule: [
113
112
  {
@@ -120,18 +119,20 @@ var scheduledJobFactory = {
120
119
  }
121
120
  ],
122
121
  timezone: "Europe/Istanbul",
123
- startDate: /* @__PURE__ */ new Date(),
122
+ startDate: startDate.toISOString(),
123
+ endDate: endDate.toISOString(),
124
124
  totalCredits: 10,
125
125
  totalPrice: 500,
126
+ // Minimum €5 (500 cents)
127
+ // Optional fields
128
+ appId: void 0,
126
129
  contentTemplate: faker.faker.lorem.paragraph(),
127
- contentRules: { tone: "friendly", length: "medium" },
128
- creditsUsed: 0,
129
- status: "draft",
130
- totalRuns: 0,
131
- successfulRuns: 0,
132
- failedRuns: 0,
133
- pendingPayment: 0,
134
- metadata: {},
130
+ contentRules: {
131
+ tone: "friendly",
132
+ length: "medium",
133
+ topics: ["tech", "ai"],
134
+ hashtags: ["#test"]
135
+ },
135
136
  ...overrides
136
137
  };
137
138
  },
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/api/client.ts","../src/fixtures/api/scheduledJobs.ts","../src/index.ts"],"names":["request","faker","dotenv"],"mappings":"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","file":"index.js","sourcesContent":["import { type APIRequestContext, request } from \"@playwright/test\"\n\nexport class APIClient {\n private context: APIRequestContext | null = null\n private baseURL: string\n private token?: string\n\n constructor(baseURL: string) {\n this.baseURL = baseURL\n }\n\n async init() {\n this.context = await request.newContext({\n baseURL: this.baseURL,\n })\n }\n\n async authenticate(email: string, password: string) {\n if (!this.context) {\n throw new Error(\"Client not initialized. Call init() first.\")\n }\n\n const response = await this.context.post(\"/api/auth/signin/password\", {\n data: { email, password },\n })\n\n if (!response.ok()) {\n const error = await response.text()\n throw new Error(`Authentication failed: ${error}`)\n }\n\n const data = await response.json()\n this.token = data.token\n return data\n }\n\n async get(path: string, options?: { params?: Record<string, string> }) {\n if (!this.context) {\n throw new Error(\"Client not initialized. Call init() first.\")\n }\n\n return this.context.get(path, {\n headers: this.token ? { Authorization: `Bearer ${this.token}` } : {},\n params: options?.params,\n })\n }\n\n async post(path: string, data?: unknown) {\n if (!this.context) {\n throw new Error(\"Client not initialized. Call init() first.\")\n }\n\n return this.context.post(path, {\n data,\n headers: this.token\n ? {\n Authorization: `Bearer ${this.token}`,\n \"Content-Type\": \"application/json\",\n }\n : { \"Content-Type\": \"application/json\" },\n })\n }\n\n async patch(path: string, data: unknown) {\n if (!this.context) {\n throw new Error(\"Client not initialized. Call init() first.\")\n }\n\n return this.context.patch(path, {\n data,\n headers: this.token\n ? {\n Authorization: `Bearer ${this.token}`,\n \"Content-Type\": \"application/json\",\n }\n : { \"Content-Type\": \"application/json\" },\n })\n }\n\n async delete(path: string) {\n if (!this.context) {\n throw new Error(\"Client not initialized. Call init() first.\")\n }\n\n return this.context.delete(path, {\n headers: this.token ? { Authorization: `Bearer ${this.token}` } : {},\n })\n }\n\n async dispose() {\n if (this.context) {\n await this.context.dispose()\n this.context = null\n }\n }\n}\n","import { faker } from \"@faker-js/faker\"\n\nexport interface ScheduledJob {\n id?: string\n appId?: string\n createPending?: boolean\n name: string\n scheduleType: string\n jobType: string\n frequency: \"once\" | \"daily\" | \"weekly\" | \"custom\"\n schedule: Array<{\n time: string\n postType: string\n model: string\n charLimit: number\n credits: number\n intervalMinutes?: number\n generateImage?: boolean\n generateVideo?: boolean\n fetchNews?: boolean\n }>\n timezone: string\n startDate: Date\n endDate?: Date\n totalCredits: number\n totalPrice: number\n contentTemplate?: string | null\n contentRules?: Record<string, unknown>\n creditsUsed?: number\n status?:\n | \"draft\"\n | \"pending_payment\"\n | \"active\"\n | \"paused\"\n | \"completed\"\n | \"canceled\"\n lastRunAt?: Date | null\n nextRunAt?: Date | null\n totalRuns?: number\n successfulRuns?: number\n failedRuns?: number\n failureReason?: string | null\n pendingPayment?: number | null\n calendarEventId?: string | null\n metadata?: Record<string, unknown>\n createdOn?: Date\n updatedOn?: Date\n}\n\nexport const scheduledJobFactory = {\n build(overrides?: Partial<ScheduledJob>): ScheduledJob {\n return {\n id: faker.string.uuid(),\n createPending: true,\n name: faker.lorem.words(3),\n scheduleType: \"tribe\",\n jobType: \"post\",\n frequency: \"daily\",\n schedule: [\n {\n time: \"09:00\",\n postType: \"post\",\n model: \"sushi\",\n charLimit: 500,\n credits: 10,\n intervalMinutes: 60,\n },\n ],\n timezone: \"Europe/Istanbul\",\n startDate: new Date(),\n totalCredits: 10,\n totalPrice: 500,\n contentTemplate: faker.lorem.paragraph(),\n contentRules: { tone: \"friendly\", length: \"medium\" },\n creditsUsed: 0,\n status: \"draft\",\n totalRuns: 0,\n successfulRuns: 0,\n failedRuns: 0,\n pendingPayment: 0,\n metadata: {},\n ...overrides,\n }\n },\n\n buildMany(count: number, overrides?: Partial<ScheduledJob>): ScheduledJob[] {\n return Array.from({ length: count }, () => this.build(overrides))\n },\n}\n","import type { Page } from \"@playwright/test\"\nimport * as dotenv from \"dotenv\"\n\ndotenv.config()\n\n// API Test Utilitiels\nexport { APIClient } from \"./api/client\"\nexport type { ScheduledJob } from \"./fixtures/api/scheduledJobs\"\nexport { scheduledJobFactory } from \"./fixtures/api/scheduledJobs\"\n\nexport type modelName = \"chatGPT\" | \"claude\" | \"gemini\" | \"sushi\" | \"perplexity\"\n\nexport const TEST_GUEST_FINGERPRINTS = (\n process.env.TEST_GUEST_FINGERPRINTS?.split(\",\") || []\n).filter((fp) => fp)\nexport const TEST_MEMBER_FINGERPRINTS = (\n process.env.TEST_MEMBER_FINGERPRINTS?.split(\",\") || []\n).filter((fp) => fp)\nexport const TEST_MEMBER_EMAILS = (\n process.env.TEST_MEMBER_EMAILS?.split(\",\") || []\n).filter((email) => email)\n\nexport const VEX_TEST_EMAIL = process.env.VEX_TEST_EMAIL!\n\nexport const VEX_TEST_PASSWORD = process.env.VEX_TEST_PASSWORD!\nexport const VEX_TEST_FINGERPRINT = TEST_MEMBER_FINGERPRINTS?.[0] || \"\"\nexport const VEX_TEST_EMAIL_2 = process.env.VEX_TEST_EMAIL_2!\nexport const VEX_TEST_PASSWORD_2 = process.env.VEX_TEST_PASSWORD_2!\nexport const VEX_TEST_FINGERPRINT_2 = TEST_MEMBER_FINGERPRINTS?.[1] || \"\"\nexport const VEX_TEST_EMAIL_3 = process.env.VEX_TEST_EMAIL_3!\nexport const VEX_TEST_PASSWORD_3 = process.env.VEX_TEST_PASSWORD_3!\nexport const VEX_TEST_PASSWORD_4 = process.env.VEX_TEST_PASSWORD_4!\n\nexport const VEX_TEST_EMAIL_4 = process.env.VEX_TEST_EMAIL_4!\n\nexport const VEX_TEST_FINGERPRINT_3 = TEST_MEMBER_FINGERPRINTS?.[2] || \"\"\nexport const VEX_TEST_FINGERPRINT_4 = TEST_MEMBER_FINGERPRINTS?.[3] || \"\"\n\nexport const VEX_LIVE_FINGERPRINTS = (\n process.env.VEX_LIVE_FINGERPRINTS?.split(\",\") || []\n).filter((fp) => fp)\n\nexport const VEX_LIVE_FINGERPRINT = VEX_LIVE_FINGERPRINTS[0] || \"\"\nexport const VEX_LIVE_FINGERPRINT_2 = VEX_LIVE_FINGERPRINTS[1] || \"\"\nexport const VEX_LIVE_FINGERPRINT_3 = VEX_LIVE_FINGERPRINTS[2] || \"\"\n\nexport const TEST_URL =\n process.env.TEST_URL! || process.env.PLAYWRIGHT_BASE_URL!\n\nexport const wait = (ms: number) =>\n new Promise((resolve) => setTimeout(resolve, ms))\nexport const isCI = process.env.VITE_CI || process.env.CI\n\nconst getURL = (\n {\n isLive = false,\n isMember = false,\n path = \"\",\n fingerprint = \"\",\n app = \"\",\n }: {\n isLive?: boolean\n isMember?: boolean\n path?: string\n fingerprint?: string\n app?: string\n } = {\n isLive: false,\n isMember: false,\n path: \"\",\n fingerprint: \"\",\n app: \"\",\n },\n) => {\n const base = TEST_URL\n const fp = isMember\n ? isLive\n ? VEX_LIVE_FINGERPRINT_2\n : fingerprint || TEST_MEMBER_FINGERPRINTS[0] || \"\"\n : isLive\n ? VEX_LIVE_FINGERPRINT\n : fingerprint || TEST_GUEST_FINGERPRINTS[0] || \"\"\n\n const appParam = app ? `&app=${app}` : \"\"\n const url = `${base}${path}?fp=${fp}${appParam}`\n\n return url\n}\n\nexport const getModelCredits = (model: string) =>\n model === \"chatGPT\" || model === \"gemini\"\n ? 4\n : model === \"claude\" || model === \"perplexity\"\n ? 3\n : 2\n\nexport const storeApps = [\n \"vex\",\n \"chrry\",\n \"atlas\",\n \"vault\",\n \"claude\",\n \"search\",\n \"sushi\",\n \"zarathustra\",\n \"popcorn\",\n]\n\nconst simulateInputPaste = async (page: Page, text: string) => {\n await page.evaluate((content) => {\n const textarea = document.querySelector(\n 'textarea[data-testid=\"chat-textarea\"]',\n ) as HTMLTextAreaElement\n if (!textarea) return\n\n // Create a basic event\n const pasteEvent = new Event(\"paste\", {\n bubbles: true,\n cancelable: true,\n })\n\n // Add clipboardData getter\n Object.defineProperty(pasteEvent, \"clipboardData\", {\n value: {\n getData: () => content,\n types: [\"text/plain\"],\n files: [],\n items: [\n {\n kind: \"string\",\n type: \"text/plain\",\n getAsString: (callback: (text: string) => void) =>\n callback(content),\n },\n ],\n },\n writable: false,\n })\n\n // Dispatch the event\n textarea.dispatchEvent(pasteEvent)\n\n // Set the value directly after the paste event\n textarea.value = content\n\n // Trigger input event to simulate actual typing\n const inputEvent = new Event(\"input\", { bubbles: true })\n textarea.dispatchEvent(inputEvent)\n }, text)\n}\n\nconst simulatePaste = async (page: Page, text: string) => {\n // Use Playwright's built-in clipboard API\n await page.evaluate(async (content) => {\n // Write to clipboard\n await navigator.clipboard.writeText(content)\n\n // Find the paste button and click it\n const pasteButton = document.querySelector(\n '[data-testid*=\"artifacts-paste-button\"]',\n ) as HTMLButtonElement\n if (pasteButton) {\n pasteButton.click()\n }\n }, text)\n}\n\nfunction capitalizeFirstLetter(val: string) {\n return String(val).charAt(0).toUpperCase() + String(val).slice(1)\n}\n\nconst logs = new Map<string, number>() // msg → timestamp\nexport const log = ({ page }: { page: Page }) => {\n page.on(\"console\", (msg) => {\n const now = Date.now()\n const lastSeen = logs.get(msg.text())\n\n // Only skip if seen within last 5 seconds\n if (lastSeen && now - lastSeen < 5000) return\n\n msg.type() !== \"warning\" &&\n !msg.text().includes(\"token\") &&\n !msg.text().includes(\"fp\") &&\n console.log(`[browser][${msg.type()}] ${msg.text()}`)\n logs.set(msg.text(), now)\n })\n}\n\nexport { capitalizeFirstLetter, getURL, simulateInputPaste, simulatePaste }\n"]}
1
+ {"version":3,"sources":["../src/api/client.ts","../src/fixtures/api/scheduledJobs.ts","../src/index.ts"],"names":["request","faker","dotenv"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAEO,IAAM,YAAN,MAAgB;AAAA,EACb,OAAA,GAAoC,IAAA;AAAA,EACpC,OAAA;AAAA,EACA,KAAA;AAAA,EAER,YAAY,OAAA,EAAiB;AAC3B,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AAAA,EAEA,MAAM,IAAA,GAAO;AACX,IAAA,IAAA,CAAK,OAAA,GAAU,MAAMA,YAAA,CAAQ,UAAA,CAAW;AAAA,MACtC,SAAS,IAAA,CAAK;AAAA,KACf,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,YAAA,CAAa,KAAA,EAAe,QAAA,EAAkB;AAClD,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AACjB,MAAA,MAAM,IAAI,MAAM,4CAA4C,CAAA;AAAA,IAC9D;AAEA,IAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,OAAA,CAAQ,KAAK,2BAAA,EAA6B;AAAA,MACpE,IAAA,EAAM,EAAE,KAAA,EAAO,QAAA;AAAS,KACzB,CAAA;AAED,IAAA,IAAI,CAAC,QAAA,CAAS,EAAA,EAAG,EAAG;AAClB,MAAA,MAAM,KAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAClC,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,uBAAA,EAA0B,KAAK,CAAA,CAAE,CAAA;AAAA,IACnD;AAEA,IAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,IAAA,EAAK;AACjC,IAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,KAAA;AAClB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,GAAA,CAAI,IAAA,EAAc,OAAA,EAA+C;AACrE,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AACjB,MAAA,MAAM,IAAI,MAAM,4CAA4C,CAAA;AAAA,IAC9D;AAEA,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,IAAA,EAAM;AAAA,MAC5B,OAAA,EAAS,IAAA,CAAK,KAAA,GAAQ,EAAE,aAAA,EAAe,UAAU,IAAA,CAAK,KAAK,CAAA,CAAA,EAAG,GAAI,EAAC;AAAA,MACnE,QAAQ,OAAA,EAAS;AAAA,KAClB,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,IAAA,CAAK,IAAA,EAAc,IAAA,EAAgB;AACvC,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AACjB,MAAA,MAAM,IAAI,MAAM,4CAA4C,CAAA;AAAA,IAC9D;AAEA,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,IAAA,EAAM;AAAA,MAC7B,IAAA;AAAA,MACA,OAAA,EAAS,KAAK,KAAA,GACV;AAAA,QACE,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,KAAK,CAAA,CAAA;AAAA,QACnC,cAAA,EAAgB;AAAA,OAClB,GACA,EAAE,cAAA,EAAgB,kBAAA;AAAmB,KAC1C,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,KAAA,CAAM,IAAA,EAAc,IAAA,EAAe;AACvC,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AACjB,MAAA,MAAM,IAAI,MAAM,4CAA4C,CAAA;AAAA,IAC9D;AAEA,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,KAAA,CAAM,IAAA,EAAM;AAAA,MAC9B,IAAA;AAAA,MACA,OAAA,EAAS,KAAK,KAAA,GACV;AAAA,QACE,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,KAAK,CAAA,CAAA;AAAA,QACnC,cAAA,EAAgB;AAAA,OAClB,GACA,EAAE,cAAA,EAAgB,kBAAA;AAAmB,KAC1C,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,OAAO,IAAA,EAAc;AACzB,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AACjB,MAAA,MAAM,IAAI,MAAM,4CAA4C,CAAA;AAAA,IAC9D;AAEA,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,IAAA,EAAM;AAAA,MAC/B,OAAA,EAAS,IAAA,CAAK,KAAA,GAAQ,EAAE,aAAA,EAAe,UAAU,IAAA,CAAK,KAAK,CAAA,CAAA,EAAG,GAAI;AAAC,KACpE,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,OAAA,GAAU;AACd,IAAA,IAAI,KAAK,OAAA,EAAS;AAChB,MAAA,MAAM,IAAA,CAAK,QAAQ,OAAA,EAAQ;AAC3B,MAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AAAA,IACjB;AAAA,EACF;AACF;ACxDO,IAAM,mBAAA,GAAsB;AAAA,EACjC,MAAM,SAAA,EAA6D;AACjE,IAAA,MAAM,SAAA,uBAAgB,IAAA,EAAK;AAC3B,IAAA,MAAM,OAAA,GAAU,IAAI,IAAA,CAAK,SAAS,CAAA;AAClC,IAAA,OAAA,CAAQ,OAAA,CAAQ,OAAA,CAAQ,OAAA,EAAQ,GAAI,CAAC,CAAA;AAErC,IAAA,OAAO;AAAA;AAAA,MAEL,SAAA,EAAW,OAAA;AAAA,MACX,QAAA,EAAU;AAAA,QACR;AAAA,UACE,IAAA,EAAM,OAAA;AAAA,UACN,QAAA,EAAU,MAAA;AAAA,UACV,KAAA,EAAO,OAAA;AAAA,UACP,SAAA,EAAW,GAAA;AAAA,UACX,OAAA,EAAS,EAAA;AAAA,UACT,eAAA,EAAiB;AAAA;AACnB,OACF;AAAA,MACA,QAAA,EAAU,iBAAA;AAAA,MACV,SAAA,EAAW,UAAU,WAAA,EAAY;AAAA,MACjC,OAAA,EAAS,QAAQ,WAAA,EAAY;AAAA,MAC7B,YAAA,EAAc,EAAA;AAAA,MACd,UAAA,EAAY,GAAA;AAAA;AAAA;AAAA,MAGZ,KAAA,EAAO,MAAA;AAAA,MACP,eAAA,EAAiBC,WAAA,CAAM,KAAA,CAAM,SAAA,EAAU;AAAA,MACvC,YAAA,EAAc;AAAA,QACZ,IAAA,EAAM,UAAA;AAAA,QACN,MAAA,EAAQ,QAAA;AAAA,QACR,MAAA,EAAQ,CAAC,MAAA,EAAQ,IAAI,CAAA;AAAA,QACrB,QAAA,EAAU,CAAC,OAAO;AAAA,OACpB;AAAA,MAEA,GAAG;AAAA,KACL;AAAA,EACF,CAAA;AAAA,EAEA,SAAA,CACE,OACA,SAAA,EACsB;AACtB,IAAA,OAAO,KAAA,CAAM,IAAA,CAAK,EAAE,MAAA,EAAQ,KAAA,IAAS,MAAM,IAAA,CAAK,KAAA,CAAM,SAAS,CAAC,CAAA;AAAA,EAClE;AACF;;;ACjFOC,iBAAA,CAAA,MAAA,EAAO;AASP,IAAM,uBAAA,GAAA,CACX,OAAA,CAAQ,GAAA,CAAI,uBAAA,EAAyB,KAAA,CAAM,GAAG,CAAA,IAAK,EAAC,EACpD,MAAA,CAAO,CAAC,EAAA,KAAO,EAAE;AACZ,IAAM,wBAAA,GAAA,CACX,OAAA,CAAQ,GAAA,CAAI,wBAAA,EAA0B,KAAA,CAAM,GAAG,CAAA,IAAK,EAAC,EACrD,MAAA,CAAO,CAAC,EAAA,KAAO,EAAE;AACZ,IAAM,kBAAA,GAAA,CACX,OAAA,CAAQ,GAAA,CAAI,kBAAA,EAAoB,KAAA,CAAM,GAAG,CAAA,IAAK,EAAC,EAC/C,MAAA,CAAO,CAAC,KAAA,KAAU,KAAK;AAElB,IAAM,cAAA,GAAiB,QAAQ,GAAA,CAAI;AAEnC,IAAM,iBAAA,GAAoB,QAAQ,GAAA,CAAI;AACtC,IAAM,oBAAA,GAAuB,wBAAA,GAA2B,CAAC,CAAA,IAAK;AAC9D,IAAM,gBAAA,GAAmB,QAAQ,GAAA,CAAI;AACrC,IAAM,mBAAA,GAAsB,QAAQ,GAAA,CAAI;AACxC,IAAM,sBAAA,GAAyB,wBAAA,GAA2B,CAAC,CAAA,IAAK;AAChE,IAAM,gBAAA,GAAmB,QAAQ,GAAA,CAAI;AACrC,IAAM,mBAAA,GAAsB,QAAQ,GAAA,CAAI;AACxC,IAAM,mBAAA,GAAsB,QAAQ,GAAA,CAAI;AAExC,IAAM,gBAAA,GAAmB,QAAQ,GAAA,CAAI;AAErC,IAAM,sBAAA,GAAyB,wBAAA,GAA2B,CAAC,CAAA,IAAK;AAChE,IAAM,sBAAA,GAAyB,wBAAA,GAA2B,CAAC,CAAA,IAAK;AAEhE,IAAM,qBAAA,GAAA,CACX,OAAA,CAAQ,GAAA,CAAI,qBAAA,EAAuB,KAAA,CAAM,GAAG,CAAA,IAAK,EAAC,EAClD,MAAA,CAAO,CAAC,EAAA,KAAO,EAAE;AAEZ,IAAM,oBAAA,GAAuB,qBAAA,CAAsB,CAAC,CAAA,IAAK;AACzD,IAAM,sBAAA,GAAyB,qBAAA,CAAsB,CAAC,CAAA,IAAK;AAC3D,IAAM,sBAAA,GAAyB,qBAAA,CAAsB,CAAC,CAAA,IAAK;AAE3D,IAAM,QAAA,GACX,OAAA,CAAQ,GAAA,CAAI,QAAA,IAAa,QAAQ,GAAA,CAAI;AAEhC,IAAM,IAAA,GAAO,CAAC,EAAA,KACnB,IAAI,OAAA,CAAQ,CAAC,OAAA,KAAY,UAAA,CAAW,OAAA,EAAS,EAAE,CAAC;AAC3C,IAAM,IAAA,GAAO,OAAA,CAAQ,GAAA,CAAI,OAAA,IAAW,QAAQ,GAAA,CAAI;AAEvD,IAAM,SAAS,CACb;AAAA,EACE,MAAA,GAAS,KAAA;AAAA,EACT,QAAA,GAAW,KAAA;AAAA,EACX,IAAA,GAAO,EAAA;AAAA,EACP,WAAA,GAAc,EAAA;AAAA,EACd,GAAA,GAAM;AACR,CAAA,GAMI;AAAA,EACF,MAAA,EAAQ,KAAA;AAAA,EACR,QAAA,EAAU,KAAA;AAAA,EACV,IAAA,EAAM,EAAA;AAAA,EACN,WAAA,EAAa,EAAA;AAAA,EACb,GAAA,EAAK;AACP,CAAA,KACG;AACH,EAAA,MAAM,IAAA,GAAO,QAAA;AACb,EAAA,MAAM,EAAA,GAAK,QAAA,GACP,MAAA,GACE,sBAAA,GACA,eAAe,wBAAA,CAAyB,CAAC,CAAA,IAAK,EAAA,GAChD,MAAA,GACE,oBAAA,GACA,WAAA,IAAe,uBAAA,CAAwB,CAAC,CAAA,IAAK,EAAA;AAEnD,EAAA,MAAM,QAAA,GAAW,GAAA,GAAM,CAAA,KAAA,EAAQ,GAAG,CAAA,CAAA,GAAK,EAAA;AACvC,EAAA,MAAM,GAAA,GAAM,GAAG,IAAI,CAAA,EAAG,IAAI,CAAA,IAAA,EAAO,EAAE,GAAG,QAAQ,CAAA,CAAA;AAE9C,EAAA,OAAO,GAAA;AACT;AAEO,IAAM,eAAA,GAAkB,CAAC,KAAA,KAC9B,KAAA,KAAU,SAAA,IAAa,KAAA,KAAU,QAAA,GAC7B,CAAA,GACA,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,YAAA,GAC9B,CAAA,GACA;AAED,IAAM,SAAA,GAAY;AAAA,EACvB,KAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,aAAA;AAAA,EACA;AACF;AAEA,IAAM,kBAAA,GAAqB,OAAO,IAAA,EAAY,IAAA,KAAiB;AAC7D,EAAA,MAAM,IAAA,CAAK,QAAA,CAAS,CAAC,OAAA,KAAY;AAC/B,IAAA,MAAM,WAAW,QAAA,CAAS,aAAA;AAAA,MACxB;AAAA,KACF;AACA,IAAA,IAAI,CAAC,QAAA,EAAU;AAGf,IAAA,MAAM,UAAA,GAAa,IAAI,KAAA,CAAM,OAAA,EAAS;AAAA,MACpC,OAAA,EAAS,IAAA;AAAA,MACT,UAAA,EAAY;AAAA,KACb,CAAA;AAGD,IAAA,MAAA,CAAO,cAAA,CAAe,YAAY,eAAA,EAAiB;AAAA,MACjD,KAAA,EAAO;AAAA,QACL,SAAS,MAAM,OAAA;AAAA,QACf,KAAA,EAAO,CAAC,YAAY,CAAA;AAAA,QACpB,OAAO,EAAC;AAAA,QACR,KAAA,EAAO;AAAA,UACL;AAAA,YACE,IAAA,EAAM,QAAA;AAAA,YACN,IAAA,EAAM,YAAA;AAAA,YACN,WAAA,EAAa,CAAC,QAAA,KACZ,QAAA,CAAS,OAAO;AAAA;AACpB;AACF,OACF;AAAA,MACA,QAAA,EAAU;AAAA,KACX,CAAA;AAGD,IAAA,QAAA,CAAS,cAAc,UAAU,CAAA;AAGjC,IAAA,QAAA,CAAS,KAAA,GAAQ,OAAA;AAGjB,IAAA,MAAM,aAAa,IAAI,KAAA,CAAM,SAAS,EAAE,OAAA,EAAS,MAAM,CAAA;AACvD,IAAA,QAAA,CAAS,cAAc,UAAU,CAAA;AAAA,EACnC,GAAG,IAAI,CAAA;AACT;AAEA,IAAM,aAAA,GAAgB,OAAO,IAAA,EAAY,IAAA,KAAiB;AAExD,EAAA,MAAM,IAAA,CAAK,QAAA,CAAS,OAAO,OAAA,KAAY;AAErC,IAAA,MAAM,SAAA,CAAU,SAAA,CAAU,SAAA,CAAU,OAAO,CAAA;AAG3C,IAAA,MAAM,cAAc,QAAA,CAAS,aAAA;AAAA,MAC3B;AAAA,KACF;AACA,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,WAAA,CAAY,KAAA,EAAM;AAAA,IACpB;AAAA,EACF,GAAG,IAAI,CAAA;AACT;AAEA,SAAS,sBAAsB,GAAA,EAAa;AAC1C,EAAA,OAAO,MAAA,CAAO,GAAG,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAY,GAAI,MAAA,CAAO,GAAG,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA;AAClE;AAEA,IAAM,IAAA,uBAAW,GAAA,EAAoB;AAC9B,IAAM,GAAA,GAAM,CAAC,EAAE,IAAA,EAAK,KAAsB;AAC/C,EAAA,IAAA,CAAK,EAAA,CAAG,SAAA,EAAW,CAAC,GAAA,KAAQ;AAC1B,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,MAAM,CAAA;AAGpC,IAAA,IAAI,QAAA,IAAY,GAAA,GAAM,QAAA,GAAW,GAAA,EAAM;AAEvC,IAAA,GAAA,CAAI,IAAA,EAAK,KAAM,SAAA,IACb,CAAC,GAAA,CAAI,IAAA,EAAK,CAAE,QAAA,CAAS,OAAO,CAAA,IAC5B,CAAC,GAAA,CAAI,IAAA,EAAK,CAAE,QAAA,CAAS,IAAI,CAAA,IACzB,OAAA,CAAQ,GAAA,CAAI,CAAA,UAAA,EAAa,GAAA,CAAI,IAAA,EAAM,CAAA,EAAA,EAAK,GAAA,CAAI,IAAA,EAAM,CAAA,CAAE,CAAA;AACtD,IAAA,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,IAAA,EAAK,EAAG,GAAG,CAAA;AAAA,EAC1B,CAAC,CAAA;AACH","file":"index.js","sourcesContent":["import { type APIRequestContext, request } from \"@playwright/test\"\n\nexport class APIClient {\n private context: APIRequestContext | null = null\n private baseURL: string\n private token?: string\n\n constructor(baseURL: string) {\n this.baseURL = baseURL\n }\n\n async init() {\n this.context = await request.newContext({\n baseURL: this.baseURL,\n })\n }\n\n async authenticate(email: string, password: string) {\n if (!this.context) {\n throw new Error(\"Client not initialized. Call init() first.\")\n }\n\n const response = await this.context.post(\"/api/auth/signin/password\", {\n data: { email, password },\n })\n\n if (!response.ok()) {\n const error = await response.text()\n throw new Error(`Authentication failed: ${error}`)\n }\n\n const data = await response.json()\n this.token = data.token\n return data\n }\n\n async get(path: string, options?: { params?: Record<string, string> }) {\n if (!this.context) {\n throw new Error(\"Client not initialized. Call init() first.\")\n }\n\n return this.context.get(path, {\n headers: this.token ? { Authorization: `Bearer ${this.token}` } : {},\n params: options?.params,\n })\n }\n\n async post(path: string, data?: unknown) {\n if (!this.context) {\n throw new Error(\"Client not initialized. Call init() first.\")\n }\n\n return this.context.post(path, {\n data,\n headers: this.token\n ? {\n Authorization: `Bearer ${this.token}`,\n \"Content-Type\": \"application/json\",\n }\n : { \"Content-Type\": \"application/json\" },\n })\n }\n\n async patch(path: string, data: unknown) {\n if (!this.context) {\n throw new Error(\"Client not initialized. Call init() first.\")\n }\n\n return this.context.patch(path, {\n data,\n headers: this.token\n ? {\n Authorization: `Bearer ${this.token}`,\n \"Content-Type\": \"application/json\",\n }\n : { \"Content-Type\": \"application/json\" },\n })\n }\n\n async delete(path: string) {\n if (!this.context) {\n throw new Error(\"Client not initialized. Call init() first.\")\n }\n\n return this.context.delete(path, {\n headers: this.token ? { Authorization: `Bearer ${this.token}` } : {},\n })\n }\n\n async dispose() {\n if (this.context) {\n await this.context.dispose()\n this.context = null\n }\n }\n}\n","import { faker } from \"@faker-js/faker\"\n\n/**\n * Tribe Schedule Fixture\n * Matches tribeScheduleSchema from @chrryai/chrry/schemas/tribeScheduleSchema\n */\n\n// Alias for backward compatibility\nexport type ScheduledJob = TribeScheduleInput\n\nexport interface TribeScheduleInput {\n sessionId?: string\n appId?: string\n schedule: Array<{\n time: string\n postType: string\n model: string\n charLimit: number\n credits: number\n intervalMinutes?: number\n generateImage?: boolean\n generateVideo?: boolean\n fetchNews?: boolean\n }>\n frequency: \"once\" | \"daily\" | \"weekly\" | \"custom\"\n startDate: string // ISO date string\n endDate?: string // ISO date string\n contentTemplate?: string\n contentRules?: {\n tone?: string\n length?: string\n topics?: string[]\n hashtags?: string[]\n }\n totalCredits: number\n totalPrice: number\n timezone: string\n}\n\nexport const scheduledJobFactory = {\n build(overrides?: Partial<TribeScheduleInput>): TribeScheduleInput {\n const startDate = new Date()\n const endDate = new Date(startDate)\n endDate.setDate(endDate.getDate() + 7)\n\n return {\n // Required fields per tribeScheduleSchema\n frequency: \"daily\",\n schedule: [\n {\n time: \"09:00\",\n postType: \"post\",\n model: \"sushi\",\n charLimit: 500,\n credits: 10,\n intervalMinutes: 60,\n },\n ],\n timezone: \"Europe/Istanbul\",\n startDate: startDate.toISOString(),\n endDate: endDate.toISOString(),\n totalCredits: 10,\n totalPrice: 500, // Minimum €5 (500 cents)\n\n // Optional fields\n appId: undefined,\n contentTemplate: faker.lorem.paragraph(),\n contentRules: {\n tone: \"friendly\",\n length: \"medium\",\n topics: [\"tech\", \"ai\"],\n hashtags: [\"#test\"],\n },\n\n ...overrides,\n }\n },\n\n buildMany(\n count: number,\n overrides?: Partial<TribeScheduleInput>,\n ): TribeScheduleInput[] {\n return Array.from({ length: count }, () => this.build(overrides))\n },\n}\n","import type { Page } from \"@playwright/test\"\nimport * as dotenv from \"dotenv\"\n\ndotenv.config()\n\n// API Test Utilitiels\nexport { APIClient } from \"./api/client\"\nexport type { ScheduledJob } from \"./fixtures/api/scheduledJobs\"\nexport { scheduledJobFactory } from \"./fixtures/api/scheduledJobs\"\n\nexport type modelName = \"chatGPT\" | \"claude\" | \"gemini\" | \"sushi\" | \"perplexity\"\n\nexport const TEST_GUEST_FINGERPRINTS = (\n process.env.TEST_GUEST_FINGERPRINTS?.split(\",\") || []\n).filter((fp) => fp)\nexport const TEST_MEMBER_FINGERPRINTS = (\n process.env.TEST_MEMBER_FINGERPRINTS?.split(\",\") || []\n).filter((fp) => fp)\nexport const TEST_MEMBER_EMAILS = (\n process.env.TEST_MEMBER_EMAILS?.split(\",\") || []\n).filter((email) => email)\n\nexport const VEX_TEST_EMAIL = process.env.VEX_TEST_EMAIL!\n\nexport const VEX_TEST_PASSWORD = process.env.VEX_TEST_PASSWORD!\nexport const VEX_TEST_FINGERPRINT = TEST_MEMBER_FINGERPRINTS?.[0] || \"\"\nexport const VEX_TEST_EMAIL_2 = process.env.VEX_TEST_EMAIL_2!\nexport const VEX_TEST_PASSWORD_2 = process.env.VEX_TEST_PASSWORD_2!\nexport const VEX_TEST_FINGERPRINT_2 = TEST_MEMBER_FINGERPRINTS?.[1] || \"\"\nexport const VEX_TEST_EMAIL_3 = process.env.VEX_TEST_EMAIL_3!\nexport const VEX_TEST_PASSWORD_3 = process.env.VEX_TEST_PASSWORD_3!\nexport const VEX_TEST_PASSWORD_4 = process.env.VEX_TEST_PASSWORD_4!\n\nexport const VEX_TEST_EMAIL_4 = process.env.VEX_TEST_EMAIL_4!\n\nexport const VEX_TEST_FINGERPRINT_3 = TEST_MEMBER_FINGERPRINTS?.[2] || \"\"\nexport const VEX_TEST_FINGERPRINT_4 = TEST_MEMBER_FINGERPRINTS?.[3] || \"\"\n\nexport const VEX_LIVE_FINGERPRINTS = (\n process.env.VEX_LIVE_FINGERPRINTS?.split(\",\") || []\n).filter((fp) => fp)\n\nexport const VEX_LIVE_FINGERPRINT = VEX_LIVE_FINGERPRINTS[0] || \"\"\nexport const VEX_LIVE_FINGERPRINT_2 = VEX_LIVE_FINGERPRINTS[1] || \"\"\nexport const VEX_LIVE_FINGERPRINT_3 = VEX_LIVE_FINGERPRINTS[2] || \"\"\n\nexport const TEST_URL =\n process.env.TEST_URL! || process.env.PLAYWRIGHT_BASE_URL!\n\nexport const wait = (ms: number) =>\n new Promise((resolve) => setTimeout(resolve, ms))\nexport const isCI = process.env.VITE_CI || process.env.CI\n\nconst getURL = (\n {\n isLive = false,\n isMember = false,\n path = \"\",\n fingerprint = \"\",\n app = \"\",\n }: {\n isLive?: boolean\n isMember?: boolean\n path?: string\n fingerprint?: string\n app?: string\n } = {\n isLive: false,\n isMember: false,\n path: \"\",\n fingerprint: \"\",\n app: \"\",\n },\n) => {\n const base = TEST_URL\n const fp = isMember\n ? isLive\n ? VEX_LIVE_FINGERPRINT_2\n : fingerprint || TEST_MEMBER_FINGERPRINTS[0] || \"\"\n : isLive\n ? VEX_LIVE_FINGERPRINT\n : fingerprint || TEST_GUEST_FINGERPRINTS[0] || \"\"\n\n const appParam = app ? `&app=${app}` : \"\"\n const url = `${base}${path}?fp=${fp}${appParam}`\n\n return url\n}\n\nexport const getModelCredits = (model: string) =>\n model === \"chatGPT\" || model === \"gemini\"\n ? 4\n : model === \"claude\" || model === \"perplexity\"\n ? 3\n : 2\n\nexport const storeApps = [\n \"vex\",\n \"chrry\",\n \"atlas\",\n \"vault\",\n \"claude\",\n \"search\",\n \"sushi\",\n \"zarathustra\",\n \"popcorn\",\n]\n\nconst simulateInputPaste = async (page: Page, text: string) => {\n await page.evaluate((content) => {\n const textarea = document.querySelector(\n 'textarea[data-testid=\"chat-textarea\"]',\n ) as HTMLTextAreaElement\n if (!textarea) return\n\n // Create a basic event\n const pasteEvent = new Event(\"paste\", {\n bubbles: true,\n cancelable: true,\n })\n\n // Add clipboardData getter\n Object.defineProperty(pasteEvent, \"clipboardData\", {\n value: {\n getData: () => content,\n types: [\"text/plain\"],\n files: [],\n items: [\n {\n kind: \"string\",\n type: \"text/plain\",\n getAsString: (callback: (text: string) => void) =>\n callback(content),\n },\n ],\n },\n writable: false,\n })\n\n // Dispatch the event\n textarea.dispatchEvent(pasteEvent)\n\n // Set the value directly after the paste event\n textarea.value = content\n\n // Trigger input event to simulate actual typing\n const inputEvent = new Event(\"input\", { bubbles: true })\n textarea.dispatchEvent(inputEvent)\n }, text)\n}\n\nconst simulatePaste = async (page: Page, text: string) => {\n // Use Playwright's built-in clipboard API\n await page.evaluate(async (content) => {\n // Write to clipboard\n await navigator.clipboard.writeText(content)\n\n // Find the paste button and click it\n const pasteButton = document.querySelector(\n '[data-testid*=\"artifacts-paste-button\"]',\n ) as HTMLButtonElement\n if (pasteButton) {\n pasteButton.click()\n }\n }, text)\n}\n\nfunction capitalizeFirstLetter(val: string) {\n return String(val).charAt(0).toUpperCase() + String(val).slice(1)\n}\n\nconst logs = new Map<string, number>() // msg → timestamp\nexport const log = ({ page }: { page: Page }) => {\n page.on(\"console\", (msg) => {\n const now = Date.now()\n const lastSeen = logs.get(msg.text())\n\n // Only skip if seen within last 5 seconds\n if (lastSeen && now - lastSeen < 5000) return\n\n msg.type() !== \"warning\" &&\n !msg.text().includes(\"token\") &&\n !msg.text().includes(\"fp\") &&\n console.log(`[browser][${msg.type()}] ${msg.text()}`)\n logs.set(msg.text(), now)\n })\n}\n\nexport { capitalizeFirstLetter, getURL, simulateInputPaste, simulatePaste }\n"]}
package/dist/index.mjs CHANGED
@@ -80,12 +80,11 @@ var APIClient = class {
80
80
  };
81
81
  var scheduledJobFactory = {
82
82
  build(overrides) {
83
+ const startDate = /* @__PURE__ */ new Date();
84
+ const endDate = new Date(startDate);
85
+ endDate.setDate(endDate.getDate() + 7);
83
86
  return {
84
- id: faker.string.uuid(),
85
- createPending: true,
86
- name: faker.lorem.words(3),
87
- scheduleType: "tribe",
88
- jobType: "post",
87
+ // Required fields per tribeScheduleSchema
89
88
  frequency: "daily",
90
89
  schedule: [
91
90
  {
@@ -98,18 +97,20 @@ var scheduledJobFactory = {
98
97
  }
99
98
  ],
100
99
  timezone: "Europe/Istanbul",
101
- startDate: /* @__PURE__ */ new Date(),
100
+ startDate: startDate.toISOString(),
101
+ endDate: endDate.toISOString(),
102
102
  totalCredits: 10,
103
103
  totalPrice: 500,
104
+ // Minimum €5 (500 cents)
105
+ // Optional fields
106
+ appId: void 0,
104
107
  contentTemplate: faker.lorem.paragraph(),
105
- contentRules: { tone: "friendly", length: "medium" },
106
- creditsUsed: 0,
107
- status: "draft",
108
- totalRuns: 0,
109
- successfulRuns: 0,
110
- failedRuns: 0,
111
- pendingPayment: 0,
112
- metadata: {},
108
+ contentRules: {
109
+ tone: "friendly",
110
+ length: "medium",
111
+ topics: ["tech", "ai"],
112
+ hashtags: ["#test"]
113
+ },
113
114
  ...overrides
114
115
  };
115
116
  },
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/api/client.ts","../src/fixtures/api/scheduledJobs.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import { type APIRequestContext, request } from \"@playwright/test\"\n\nexport class APIClient {\n private context: APIRequestContext | null = null\n private baseURL: string\n private token?: string\n\n constructor(baseURL: string) {\n this.baseURL = baseURL\n }\n\n async init() {\n this.context = await request.newContext({\n baseURL: this.baseURL,\n })\n }\n\n async authenticate(email: string, password: string) {\n if (!this.context) {\n throw new Error(\"Client not initialized. Call init() first.\")\n }\n\n const response = await this.context.post(\"/api/auth/signin/password\", {\n data: { email, password },\n })\n\n if (!response.ok()) {\n const error = await response.text()\n throw new Error(`Authentication failed: ${error}`)\n }\n\n const data = await response.json()\n this.token = data.token\n return data\n }\n\n async get(path: string, options?: { params?: Record<string, string> }) {\n if (!this.context) {\n throw new Error(\"Client not initialized. Call init() first.\")\n }\n\n return this.context.get(path, {\n headers: this.token ? { Authorization: `Bearer ${this.token}` } : {},\n params: options?.params,\n })\n }\n\n async post(path: string, data?: unknown) {\n if (!this.context) {\n throw new Error(\"Client not initialized. Call init() first.\")\n }\n\n return this.context.post(path, {\n data,\n headers: this.token\n ? {\n Authorization: `Bearer ${this.token}`,\n \"Content-Type\": \"application/json\",\n }\n : { \"Content-Type\": \"application/json\" },\n })\n }\n\n async patch(path: string, data: unknown) {\n if (!this.context) {\n throw new Error(\"Client not initialized. Call init() first.\")\n }\n\n return this.context.patch(path, {\n data,\n headers: this.token\n ? {\n Authorization: `Bearer ${this.token}`,\n \"Content-Type\": \"application/json\",\n }\n : { \"Content-Type\": \"application/json\" },\n })\n }\n\n async delete(path: string) {\n if (!this.context) {\n throw new Error(\"Client not initialized. Call init() first.\")\n }\n\n return this.context.delete(path, {\n headers: this.token ? { Authorization: `Bearer ${this.token}` } : {},\n })\n }\n\n async dispose() {\n if (this.context) {\n await this.context.dispose()\n this.context = null\n }\n }\n}\n","import { faker } from \"@faker-js/faker\"\n\nexport interface ScheduledJob {\n id?: string\n appId?: string\n createPending?: boolean\n name: string\n scheduleType: string\n jobType: string\n frequency: \"once\" | \"daily\" | \"weekly\" | \"custom\"\n schedule: Array<{\n time: string\n postType: string\n model: string\n charLimit: number\n credits: number\n intervalMinutes?: number\n generateImage?: boolean\n generateVideo?: boolean\n fetchNews?: boolean\n }>\n timezone: string\n startDate: Date\n endDate?: Date\n totalCredits: number\n totalPrice: number\n contentTemplate?: string | null\n contentRules?: Record<string, unknown>\n creditsUsed?: number\n status?:\n | \"draft\"\n | \"pending_payment\"\n | \"active\"\n | \"paused\"\n | \"completed\"\n | \"canceled\"\n lastRunAt?: Date | null\n nextRunAt?: Date | null\n totalRuns?: number\n successfulRuns?: number\n failedRuns?: number\n failureReason?: string | null\n pendingPayment?: number | null\n calendarEventId?: string | null\n metadata?: Record<string, unknown>\n createdOn?: Date\n updatedOn?: Date\n}\n\nexport const scheduledJobFactory = {\n build(overrides?: Partial<ScheduledJob>): ScheduledJob {\n return {\n id: faker.string.uuid(),\n createPending: true,\n name: faker.lorem.words(3),\n scheduleType: \"tribe\",\n jobType: \"post\",\n frequency: \"daily\",\n schedule: [\n {\n time: \"09:00\",\n postType: \"post\",\n model: \"sushi\",\n charLimit: 500,\n credits: 10,\n intervalMinutes: 60,\n },\n ],\n timezone: \"Europe/Istanbul\",\n startDate: new Date(),\n totalCredits: 10,\n totalPrice: 500,\n contentTemplate: faker.lorem.paragraph(),\n contentRules: { tone: \"friendly\", length: \"medium\" },\n creditsUsed: 0,\n status: \"draft\",\n totalRuns: 0,\n successfulRuns: 0,\n failedRuns: 0,\n pendingPayment: 0,\n metadata: {},\n ...overrides,\n }\n },\n\n buildMany(count: number, overrides?: Partial<ScheduledJob>): ScheduledJob[] {\n return Array.from({ length: count }, () => this.build(overrides))\n },\n}\n","import type { Page } from \"@playwright/test\"\nimport * as dotenv from \"dotenv\"\n\ndotenv.config()\n\n// API Test Utilitiels\nexport { APIClient } from \"./api/client\"\nexport type { ScheduledJob } from \"./fixtures/api/scheduledJobs\"\nexport { scheduledJobFactory } from \"./fixtures/api/scheduledJobs\"\n\nexport type modelName = \"chatGPT\" | \"claude\" | \"gemini\" | \"sushi\" | \"perplexity\"\n\nexport const TEST_GUEST_FINGERPRINTS = (\n process.env.TEST_GUEST_FINGERPRINTS?.split(\",\") || []\n).filter((fp) => fp)\nexport const TEST_MEMBER_FINGERPRINTS = (\n process.env.TEST_MEMBER_FINGERPRINTS?.split(\",\") || []\n).filter((fp) => fp)\nexport const TEST_MEMBER_EMAILS = (\n process.env.TEST_MEMBER_EMAILS?.split(\",\") || []\n).filter((email) => email)\n\nexport const VEX_TEST_EMAIL = process.env.VEX_TEST_EMAIL!\n\nexport const VEX_TEST_PASSWORD = process.env.VEX_TEST_PASSWORD!\nexport const VEX_TEST_FINGERPRINT = TEST_MEMBER_FINGERPRINTS?.[0] || \"\"\nexport const VEX_TEST_EMAIL_2 = process.env.VEX_TEST_EMAIL_2!\nexport const VEX_TEST_PASSWORD_2 = process.env.VEX_TEST_PASSWORD_2!\nexport const VEX_TEST_FINGERPRINT_2 = TEST_MEMBER_FINGERPRINTS?.[1] || \"\"\nexport const VEX_TEST_EMAIL_3 = process.env.VEX_TEST_EMAIL_3!\nexport const VEX_TEST_PASSWORD_3 = process.env.VEX_TEST_PASSWORD_3!\nexport const VEX_TEST_PASSWORD_4 = process.env.VEX_TEST_PASSWORD_4!\n\nexport const VEX_TEST_EMAIL_4 = process.env.VEX_TEST_EMAIL_4!\n\nexport const VEX_TEST_FINGERPRINT_3 = TEST_MEMBER_FINGERPRINTS?.[2] || \"\"\nexport const VEX_TEST_FINGERPRINT_4 = TEST_MEMBER_FINGERPRINTS?.[3] || \"\"\n\nexport const VEX_LIVE_FINGERPRINTS = (\n process.env.VEX_LIVE_FINGERPRINTS?.split(\",\") || []\n).filter((fp) => fp)\n\nexport const VEX_LIVE_FINGERPRINT = VEX_LIVE_FINGERPRINTS[0] || \"\"\nexport const VEX_LIVE_FINGERPRINT_2 = VEX_LIVE_FINGERPRINTS[1] || \"\"\nexport const VEX_LIVE_FINGERPRINT_3 = VEX_LIVE_FINGERPRINTS[2] || \"\"\n\nexport const TEST_URL =\n process.env.TEST_URL! || process.env.PLAYWRIGHT_BASE_URL!\n\nexport const wait = (ms: number) =>\n new Promise((resolve) => setTimeout(resolve, ms))\nexport const isCI = process.env.VITE_CI || process.env.CI\n\nconst getURL = (\n {\n isLive = false,\n isMember = false,\n path = \"\",\n fingerprint = \"\",\n app = \"\",\n }: {\n isLive?: boolean\n isMember?: boolean\n path?: string\n fingerprint?: string\n app?: string\n } = {\n isLive: false,\n isMember: false,\n path: \"\",\n fingerprint: \"\",\n app: \"\",\n },\n) => {\n const base = TEST_URL\n const fp = isMember\n ? isLive\n ? VEX_LIVE_FINGERPRINT_2\n : fingerprint || TEST_MEMBER_FINGERPRINTS[0] || \"\"\n : isLive\n ? VEX_LIVE_FINGERPRINT\n : fingerprint || TEST_GUEST_FINGERPRINTS[0] || \"\"\n\n const appParam = app ? `&app=${app}` : \"\"\n const url = `${base}${path}?fp=${fp}${appParam}`\n\n return url\n}\n\nexport const getModelCredits = (model: string) =>\n model === \"chatGPT\" || model === \"gemini\"\n ? 4\n : model === \"claude\" || model === \"perplexity\"\n ? 3\n : 2\n\nexport const storeApps = [\n \"vex\",\n \"chrry\",\n \"atlas\",\n \"vault\",\n \"claude\",\n \"search\",\n \"sushi\",\n \"zarathustra\",\n \"popcorn\",\n]\n\nconst simulateInputPaste = async (page: Page, text: string) => {\n await page.evaluate((content) => {\n const textarea = document.querySelector(\n 'textarea[data-testid=\"chat-textarea\"]',\n ) as HTMLTextAreaElement\n if (!textarea) return\n\n // Create a basic event\n const pasteEvent = new Event(\"paste\", {\n bubbles: true,\n cancelable: true,\n })\n\n // Add clipboardData getter\n Object.defineProperty(pasteEvent, \"clipboardData\", {\n value: {\n getData: () => content,\n types: [\"text/plain\"],\n files: [],\n items: [\n {\n kind: \"string\",\n type: \"text/plain\",\n getAsString: (callback: (text: string) => void) =>\n callback(content),\n },\n ],\n },\n writable: false,\n })\n\n // Dispatch the event\n textarea.dispatchEvent(pasteEvent)\n\n // Set the value directly after the paste event\n textarea.value = content\n\n // Trigger input event to simulate actual typing\n const inputEvent = new Event(\"input\", { bubbles: true })\n textarea.dispatchEvent(inputEvent)\n }, text)\n}\n\nconst simulatePaste = async (page: Page, text: string) => {\n // Use Playwright's built-in clipboard API\n await page.evaluate(async (content) => {\n // Write to clipboard\n await navigator.clipboard.writeText(content)\n\n // Find the paste button and click it\n const pasteButton = document.querySelector(\n '[data-testid*=\"artifacts-paste-button\"]',\n ) as HTMLButtonElement\n if (pasteButton) {\n pasteButton.click()\n }\n }, text)\n}\n\nfunction capitalizeFirstLetter(val: string) {\n return String(val).charAt(0).toUpperCase() + String(val).slice(1)\n}\n\nconst logs = new Map<string, number>() // msg → timestamp\nexport const log = ({ page }: { page: Page }) => {\n page.on(\"console\", (msg) => {\n const now = Date.now()\n const lastSeen = logs.get(msg.text())\n\n // Only skip if seen within last 5 seconds\n if (lastSeen && now - lastSeen < 5000) return\n\n msg.type() !== \"warning\" &&\n !msg.text().includes(\"token\") &&\n !msg.text().includes(\"fp\") &&\n console.log(`[browser][${msg.type()}] ${msg.text()}`)\n logs.set(msg.text(), now)\n })\n}\n\nexport { capitalizeFirstLetter, getURL, simulateInputPaste, simulatePaste }\n"]}
1
+ {"version":3,"sources":["../src/api/client.ts","../src/fixtures/api/scheduledJobs.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import { type APIRequestContext, request } from \"@playwright/test\"\n\nexport class APIClient {\n private context: APIRequestContext | null = null\n private baseURL: string\n private token?: string\n\n constructor(baseURL: string) {\n this.baseURL = baseURL\n }\n\n async init() {\n this.context = await request.newContext({\n baseURL: this.baseURL,\n })\n }\n\n async authenticate(email: string, password: string) {\n if (!this.context) {\n throw new Error(\"Client not initialized. Call init() first.\")\n }\n\n const response = await this.context.post(\"/api/auth/signin/password\", {\n data: { email, password },\n })\n\n if (!response.ok()) {\n const error = await response.text()\n throw new Error(`Authentication failed: ${error}`)\n }\n\n const data = await response.json()\n this.token = data.token\n return data\n }\n\n async get(path: string, options?: { params?: Record<string, string> }) {\n if (!this.context) {\n throw new Error(\"Client not initialized. Call init() first.\")\n }\n\n return this.context.get(path, {\n headers: this.token ? { Authorization: `Bearer ${this.token}` } : {},\n params: options?.params,\n })\n }\n\n async post(path: string, data?: unknown) {\n if (!this.context) {\n throw new Error(\"Client not initialized. Call init() first.\")\n }\n\n return this.context.post(path, {\n data,\n headers: this.token\n ? {\n Authorization: `Bearer ${this.token}`,\n \"Content-Type\": \"application/json\",\n }\n : { \"Content-Type\": \"application/json\" },\n })\n }\n\n async patch(path: string, data: unknown) {\n if (!this.context) {\n throw new Error(\"Client not initialized. Call init() first.\")\n }\n\n return this.context.patch(path, {\n data,\n headers: this.token\n ? {\n Authorization: `Bearer ${this.token}`,\n \"Content-Type\": \"application/json\",\n }\n : { \"Content-Type\": \"application/json\" },\n })\n }\n\n async delete(path: string) {\n if (!this.context) {\n throw new Error(\"Client not initialized. Call init() first.\")\n }\n\n return this.context.delete(path, {\n headers: this.token ? { Authorization: `Bearer ${this.token}` } : {},\n })\n }\n\n async dispose() {\n if (this.context) {\n await this.context.dispose()\n this.context = null\n }\n }\n}\n","import { faker } from \"@faker-js/faker\"\n\n/**\n * Tribe Schedule Fixture\n * Matches tribeScheduleSchema from @chrryai/chrry/schemas/tribeScheduleSchema\n */\n\n// Alias for backward compatibility\nexport type ScheduledJob = TribeScheduleInput\n\nexport interface TribeScheduleInput {\n sessionId?: string\n appId?: string\n schedule: Array<{\n time: string\n postType: string\n model: string\n charLimit: number\n credits: number\n intervalMinutes?: number\n generateImage?: boolean\n generateVideo?: boolean\n fetchNews?: boolean\n }>\n frequency: \"once\" | \"daily\" | \"weekly\" | \"custom\"\n startDate: string // ISO date string\n endDate?: string // ISO date string\n contentTemplate?: string\n contentRules?: {\n tone?: string\n length?: string\n topics?: string[]\n hashtags?: string[]\n }\n totalCredits: number\n totalPrice: number\n timezone: string\n}\n\nexport const scheduledJobFactory = {\n build(overrides?: Partial<TribeScheduleInput>): TribeScheduleInput {\n const startDate = new Date()\n const endDate = new Date(startDate)\n endDate.setDate(endDate.getDate() + 7)\n\n return {\n // Required fields per tribeScheduleSchema\n frequency: \"daily\",\n schedule: [\n {\n time: \"09:00\",\n postType: \"post\",\n model: \"sushi\",\n charLimit: 500,\n credits: 10,\n intervalMinutes: 60,\n },\n ],\n timezone: \"Europe/Istanbul\",\n startDate: startDate.toISOString(),\n endDate: endDate.toISOString(),\n totalCredits: 10,\n totalPrice: 500, // Minimum €5 (500 cents)\n\n // Optional fields\n appId: undefined,\n contentTemplate: faker.lorem.paragraph(),\n contentRules: {\n tone: \"friendly\",\n length: \"medium\",\n topics: [\"tech\", \"ai\"],\n hashtags: [\"#test\"],\n },\n\n ...overrides,\n }\n },\n\n buildMany(\n count: number,\n overrides?: Partial<TribeScheduleInput>,\n ): TribeScheduleInput[] {\n return Array.from({ length: count }, () => this.build(overrides))\n },\n}\n","import type { Page } from \"@playwright/test\"\nimport * as dotenv from \"dotenv\"\n\ndotenv.config()\n\n// API Test Utilitiels\nexport { APIClient } from \"./api/client\"\nexport type { ScheduledJob } from \"./fixtures/api/scheduledJobs\"\nexport { scheduledJobFactory } from \"./fixtures/api/scheduledJobs\"\n\nexport type modelName = \"chatGPT\" | \"claude\" | \"gemini\" | \"sushi\" | \"perplexity\"\n\nexport const TEST_GUEST_FINGERPRINTS = (\n process.env.TEST_GUEST_FINGERPRINTS?.split(\",\") || []\n).filter((fp) => fp)\nexport const TEST_MEMBER_FINGERPRINTS = (\n process.env.TEST_MEMBER_FINGERPRINTS?.split(\",\") || []\n).filter((fp) => fp)\nexport const TEST_MEMBER_EMAILS = (\n process.env.TEST_MEMBER_EMAILS?.split(\",\") || []\n).filter((email) => email)\n\nexport const VEX_TEST_EMAIL = process.env.VEX_TEST_EMAIL!\n\nexport const VEX_TEST_PASSWORD = process.env.VEX_TEST_PASSWORD!\nexport const VEX_TEST_FINGERPRINT = TEST_MEMBER_FINGERPRINTS?.[0] || \"\"\nexport const VEX_TEST_EMAIL_2 = process.env.VEX_TEST_EMAIL_2!\nexport const VEX_TEST_PASSWORD_2 = process.env.VEX_TEST_PASSWORD_2!\nexport const VEX_TEST_FINGERPRINT_2 = TEST_MEMBER_FINGERPRINTS?.[1] || \"\"\nexport const VEX_TEST_EMAIL_3 = process.env.VEX_TEST_EMAIL_3!\nexport const VEX_TEST_PASSWORD_3 = process.env.VEX_TEST_PASSWORD_3!\nexport const VEX_TEST_PASSWORD_4 = process.env.VEX_TEST_PASSWORD_4!\n\nexport const VEX_TEST_EMAIL_4 = process.env.VEX_TEST_EMAIL_4!\n\nexport const VEX_TEST_FINGERPRINT_3 = TEST_MEMBER_FINGERPRINTS?.[2] || \"\"\nexport const VEX_TEST_FINGERPRINT_4 = TEST_MEMBER_FINGERPRINTS?.[3] || \"\"\n\nexport const VEX_LIVE_FINGERPRINTS = (\n process.env.VEX_LIVE_FINGERPRINTS?.split(\",\") || []\n).filter((fp) => fp)\n\nexport const VEX_LIVE_FINGERPRINT = VEX_LIVE_FINGERPRINTS[0] || \"\"\nexport const VEX_LIVE_FINGERPRINT_2 = VEX_LIVE_FINGERPRINTS[1] || \"\"\nexport const VEX_LIVE_FINGERPRINT_3 = VEX_LIVE_FINGERPRINTS[2] || \"\"\n\nexport const TEST_URL =\n process.env.TEST_URL! || process.env.PLAYWRIGHT_BASE_URL!\n\nexport const wait = (ms: number) =>\n new Promise((resolve) => setTimeout(resolve, ms))\nexport const isCI = process.env.VITE_CI || process.env.CI\n\nconst getURL = (\n {\n isLive = false,\n isMember = false,\n path = \"\",\n fingerprint = \"\",\n app = \"\",\n }: {\n isLive?: boolean\n isMember?: boolean\n path?: string\n fingerprint?: string\n app?: string\n } = {\n isLive: false,\n isMember: false,\n path: \"\",\n fingerprint: \"\",\n app: \"\",\n },\n) => {\n const base = TEST_URL\n const fp = isMember\n ? isLive\n ? VEX_LIVE_FINGERPRINT_2\n : fingerprint || TEST_MEMBER_FINGERPRINTS[0] || \"\"\n : isLive\n ? VEX_LIVE_FINGERPRINT\n : fingerprint || TEST_GUEST_FINGERPRINTS[0] || \"\"\n\n const appParam = app ? `&app=${app}` : \"\"\n const url = `${base}${path}?fp=${fp}${appParam}`\n\n return url\n}\n\nexport const getModelCredits = (model: string) =>\n model === \"chatGPT\" || model === \"gemini\"\n ? 4\n : model === \"claude\" || model === \"perplexity\"\n ? 3\n : 2\n\nexport const storeApps = [\n \"vex\",\n \"chrry\",\n \"atlas\",\n \"vault\",\n \"claude\",\n \"search\",\n \"sushi\",\n \"zarathustra\",\n \"popcorn\",\n]\n\nconst simulateInputPaste = async (page: Page, text: string) => {\n await page.evaluate((content) => {\n const textarea = document.querySelector(\n 'textarea[data-testid=\"chat-textarea\"]',\n ) as HTMLTextAreaElement\n if (!textarea) return\n\n // Create a basic event\n const pasteEvent = new Event(\"paste\", {\n bubbles: true,\n cancelable: true,\n })\n\n // Add clipboardData getter\n Object.defineProperty(pasteEvent, \"clipboardData\", {\n value: {\n getData: () => content,\n types: [\"text/plain\"],\n files: [],\n items: [\n {\n kind: \"string\",\n type: \"text/plain\",\n getAsString: (callback: (text: string) => void) =>\n callback(content),\n },\n ],\n },\n writable: false,\n })\n\n // Dispatch the event\n textarea.dispatchEvent(pasteEvent)\n\n // Set the value directly after the paste event\n textarea.value = content\n\n // Trigger input event to simulate actual typing\n const inputEvent = new Event(\"input\", { bubbles: true })\n textarea.dispatchEvent(inputEvent)\n }, text)\n}\n\nconst simulatePaste = async (page: Page, text: string) => {\n // Use Playwright's built-in clipboard API\n await page.evaluate(async (content) => {\n // Write to clipboard\n await navigator.clipboard.writeText(content)\n\n // Find the paste button and click it\n const pasteButton = document.querySelector(\n '[data-testid*=\"artifacts-paste-button\"]',\n ) as HTMLButtonElement\n if (pasteButton) {\n pasteButton.click()\n }\n }, text)\n}\n\nfunction capitalizeFirstLetter(val: string) {\n return String(val).charAt(0).toUpperCase() + String(val).slice(1)\n}\n\nconst logs = new Map<string, number>() // msg → timestamp\nexport const log = ({ page }: { page: Page }) => {\n page.on(\"console\", (msg) => {\n const now = Date.now()\n const lastSeen = logs.get(msg.text())\n\n // Only skip if seen within last 5 seconds\n if (lastSeen && now - lastSeen < 5000) return\n\n msg.type() !== \"warning\" &&\n !msg.text().includes(\"token\") &&\n !msg.text().includes(\"fp\") &&\n console.log(`[browser][${msg.type()}] ${msg.text()}`)\n logs.set(msg.text(), now)\n })\n}\n\nexport { capitalizeFirstLetter, getURL, simulateInputPaste, simulatePaste }\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chrryai/waffles",
3
- "version": "2.3.60",
3
+ "version": "2.3.71",
4
4
  "description": "Production-ready Playwright testing utilities and helpers for modern web apps",
5
5
  "keywords": [
6
6
  "automation",
@@ -38,6 +38,9 @@
38
38
  "LICENSE"
39
39
  ],
40
40
  "scripts": {
41
+ "api:test": "playwright test --project api",
42
+ "api:test:live": "API_URL=https://api.chrry.ai playwright test --project api",
43
+ "api:test:local": "API_URL=http://localhost:3001 playwright test --project api",
41
44
  "build": "pnpm exec tsup",
42
45
  "dev": "pnpm exec tsup --watch",
43
46
  "e": "pnpm exec playwright install chromium && playwright test --project chromium",
@@ -45,18 +48,21 @@
45
48
  "ec": "pnpm exec playwright install chromium && playwright test critical.spec.ts --project chromium",
46
49
  "lint": "biome check .",
47
50
  "sync-goals": "tsx src/scripts/sync-plausible-goals.ts",
51
+ "test": "vitest run",
52
+ "test:all": "pnpm e2e && pnpm api:test",
53
+ "test:coverage": "vitest run --coverage",
54
+ "test:integration": "vitest run src/__tests__/integration --testTimeout 60000",
48
55
  "test:tauri": "TEST_URL=http://localhost:5173 playwright test --project tauri-macos",
49
- "api:test": "playwright test --project api",
50
- "api:test:local": "API_URL=http://localhost:3001 playwright test --project api",
51
- "api:test:live": "API_URL=https://api.chrry.ai playwright test --project api",
52
- "test:all": "pnpm e2e && pnpm api:test"
56
+ "test:unit": "vitest run src/__tests__/unit"
53
57
  },
54
58
  "dependencies": {
59
+ "@chrryai/machine": "workspace:*",
55
60
  "@faker-js/faker": "^9.3.0",
56
61
  "@playwright/test": "^1.49.1",
57
62
  "@types/node": "^22.18.12",
58
63
  "@types/react": "^19.1.12",
59
64
  "dotenv": "^17.3.1",
65
+ "effect": "^3.0.0",
60
66
  "uuid": "^13.0.0"
61
67
  },
62
68
  "devDependencies": {
@@ -64,7 +70,8 @@
64
70
  "eslint": "^9.0.0",
65
71
  "tsup": "^8.0.0",
66
72
  "tsx": "^4.19.3",
67
- "typescript": "^5.0.0"
73
+ "typescript": "^5.0.0",
74
+ "vitest": "^1.0.0"
68
75
  },
69
76
  "peerDependencies": {
70
77
  "@chrryai/chrry": "workspace:*",