@chrryai/waffles 2.3.45 → 2.3.47

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
@@ -1,5 +1,67 @@
1
+ import * as _playwright_test from '@playwright/test';
1
2
  import { Page } from '@playwright/test';
2
3
 
4
+ declare class APIClient {
5
+ private context;
6
+ private baseURL;
7
+ private token?;
8
+ constructor(baseURL: string);
9
+ init(): Promise<void>;
10
+ authenticate(email: string, password: string): Promise<any>;
11
+ get(path: string, options?: {
12
+ params?: Record<string, string>;
13
+ }): Promise<_playwright_test.APIResponse>;
14
+ post(path: string, data?: unknown): Promise<_playwright_test.APIResponse>;
15
+ patch(path: string, data: unknown): Promise<_playwright_test.APIResponse>;
16
+ delete(path: string): Promise<_playwright_test.APIResponse>;
17
+ dispose(): Promise<void>;
18
+ }
19
+
20
+ interface ScheduledJob {
21
+ id?: string;
22
+ appId?: string;
23
+ createPending?: boolean;
24
+ name: string;
25
+ scheduleType: string;
26
+ jobType: string;
27
+ frequency: "once" | "daily" | "weekly" | "custom";
28
+ schedule: Array<{
29
+ time: string;
30
+ postType: string;
31
+ model: string;
32
+ charLimit: number;
33
+ credits: number;
34
+ intervalMinutes?: number;
35
+ generateImage?: boolean;
36
+ generateVideo?: boolean;
37
+ fetchNews?: boolean;
38
+ }>;
39
+ timezone: string;
40
+ startDate: Date;
41
+ endDate?: Date;
42
+ totalCredits: number;
43
+ 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;
59
+ }
60
+ declare const scheduledJobFactory: {
61
+ build(overrides?: Partial<ScheduledJob>): ScheduledJob;
62
+ buildMany(count: number, overrides?: Partial<ScheduledJob>): ScheduledJob[];
63
+ };
64
+
3
65
  type modelName = "chatGPT" | "claude" | "gemini" | "sushi" | "perplexity";
4
66
  declare const TEST_GUEST_FINGERPRINTS: string[];
5
67
  declare const TEST_MEMBER_FINGERPRINTS: string[];
@@ -39,4 +101,4 @@ declare const log: ({ page }: {
39
101
  page: Page;
40
102
  }) => void;
41
103
 
42
- export { TEST_GUEST_FINGERPRINTS, TEST_MEMBER_EMAILS, TEST_MEMBER_FINGERPRINTS, TEST_URL, VEX_LIVE_FINGERPRINT, VEX_LIVE_FINGERPRINTS, VEX_LIVE_FINGERPRINT_2, VEX_LIVE_FINGERPRINT_3, VEX_TEST_EMAIL, VEX_TEST_EMAIL_2, VEX_TEST_EMAIL_3, VEX_TEST_EMAIL_4, VEX_TEST_FINGERPRINT, VEX_TEST_FINGERPRINT_2, VEX_TEST_FINGERPRINT_3, VEX_TEST_FINGERPRINT_4, VEX_TEST_PASSWORD, VEX_TEST_PASSWORD_2, VEX_TEST_PASSWORD_3, VEX_TEST_PASSWORD_4, capitalizeFirstLetter, getModelCredits, getURL, isCI, log, type modelName, simulateInputPaste, simulatePaste, storeApps, wait };
104
+ export { APIClient, type ScheduledJob, TEST_GUEST_FINGERPRINTS, TEST_MEMBER_EMAILS, TEST_MEMBER_FINGERPRINTS, TEST_URL, VEX_LIVE_FINGERPRINT, VEX_LIVE_FINGERPRINTS, VEX_LIVE_FINGERPRINT_2, VEX_LIVE_FINGERPRINT_3, VEX_TEST_EMAIL, VEX_TEST_EMAIL_2, VEX_TEST_EMAIL_3, VEX_TEST_EMAIL_4, VEX_TEST_FINGERPRINT, VEX_TEST_FINGERPRINT_2, VEX_TEST_FINGERPRINT_3, VEX_TEST_FINGERPRINT_4, VEX_TEST_PASSWORD, VEX_TEST_PASSWORD_2, VEX_TEST_PASSWORD_3, VEX_TEST_PASSWORD_4, capitalizeFirstLetter, getModelCredits, getURL, isCI, log, type modelName, scheduledJobFactory, simulateInputPaste, simulatePaste, storeApps, wait };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,67 @@
1
+ import * as _playwright_test from '@playwright/test';
1
2
  import { Page } from '@playwright/test';
2
3
 
4
+ declare class APIClient {
5
+ private context;
6
+ private baseURL;
7
+ private token?;
8
+ constructor(baseURL: string);
9
+ init(): Promise<void>;
10
+ authenticate(email: string, password: string): Promise<any>;
11
+ get(path: string, options?: {
12
+ params?: Record<string, string>;
13
+ }): Promise<_playwright_test.APIResponse>;
14
+ post(path: string, data?: unknown): Promise<_playwright_test.APIResponse>;
15
+ patch(path: string, data: unknown): Promise<_playwright_test.APIResponse>;
16
+ delete(path: string): Promise<_playwright_test.APIResponse>;
17
+ dispose(): Promise<void>;
18
+ }
19
+
20
+ interface ScheduledJob {
21
+ id?: string;
22
+ appId?: string;
23
+ createPending?: boolean;
24
+ name: string;
25
+ scheduleType: string;
26
+ jobType: string;
27
+ frequency: "once" | "daily" | "weekly" | "custom";
28
+ schedule: Array<{
29
+ time: string;
30
+ postType: string;
31
+ model: string;
32
+ charLimit: number;
33
+ credits: number;
34
+ intervalMinutes?: number;
35
+ generateImage?: boolean;
36
+ generateVideo?: boolean;
37
+ fetchNews?: boolean;
38
+ }>;
39
+ timezone: string;
40
+ startDate: Date;
41
+ endDate?: Date;
42
+ totalCredits: number;
43
+ 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;
59
+ }
60
+ declare const scheduledJobFactory: {
61
+ build(overrides?: Partial<ScheduledJob>): ScheduledJob;
62
+ buildMany(count: number, overrides?: Partial<ScheduledJob>): ScheduledJob[];
63
+ };
64
+
3
65
  type modelName = "chatGPT" | "claude" | "gemini" | "sushi" | "perplexity";
4
66
  declare const TEST_GUEST_FINGERPRINTS: string[];
5
67
  declare const TEST_MEMBER_FINGERPRINTS: string[];
@@ -39,4 +101,4 @@ declare const log: ({ page }: {
39
101
  page: Page;
40
102
  }) => void;
41
103
 
42
- export { TEST_GUEST_FINGERPRINTS, TEST_MEMBER_EMAILS, TEST_MEMBER_FINGERPRINTS, TEST_URL, VEX_LIVE_FINGERPRINT, VEX_LIVE_FINGERPRINTS, VEX_LIVE_FINGERPRINT_2, VEX_LIVE_FINGERPRINT_3, VEX_TEST_EMAIL, VEX_TEST_EMAIL_2, VEX_TEST_EMAIL_3, VEX_TEST_EMAIL_4, VEX_TEST_FINGERPRINT, VEX_TEST_FINGERPRINT_2, VEX_TEST_FINGERPRINT_3, VEX_TEST_FINGERPRINT_4, VEX_TEST_PASSWORD, VEX_TEST_PASSWORD_2, VEX_TEST_PASSWORD_3, VEX_TEST_PASSWORD_4, capitalizeFirstLetter, getModelCredits, getURL, isCI, log, type modelName, simulateInputPaste, simulatePaste, storeApps, wait };
104
+ export { APIClient, type ScheduledJob, TEST_GUEST_FINGERPRINTS, TEST_MEMBER_EMAILS, TEST_MEMBER_FINGERPRINTS, TEST_URL, VEX_LIVE_FINGERPRINT, VEX_LIVE_FINGERPRINTS, VEX_LIVE_FINGERPRINT_2, VEX_LIVE_FINGERPRINT_3, VEX_TEST_EMAIL, VEX_TEST_EMAIL_2, VEX_TEST_EMAIL_3, VEX_TEST_EMAIL_4, VEX_TEST_FINGERPRINT, VEX_TEST_FINGERPRINT_2, VEX_TEST_FINGERPRINT_3, VEX_TEST_FINGERPRINT_4, VEX_TEST_PASSWORD, VEX_TEST_PASSWORD_2, VEX_TEST_PASSWORD_3, VEX_TEST_PASSWORD_4, capitalizeFirstLetter, getModelCredits, getURL, isCI, log, type modelName, scheduledJobFactory, simulateInputPaste, simulatePaste, storeApps, wait };
package/dist/index.js CHANGED
@@ -1,6 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var dotenv = require('dotenv');
4
+ var test = require('@playwright/test');
5
+ var faker = require('@faker-js/faker');
4
6
 
5
7
  function _interopNamespace(e) {
6
8
  if (e && e.__esModule) return e;
@@ -22,6 +24,122 @@ function _interopNamespace(e) {
22
24
 
23
25
  var dotenv__namespace = /*#__PURE__*/_interopNamespace(dotenv);
24
26
 
27
+ // src/index.ts
28
+ var APIClient = class {
29
+ context = null;
30
+ baseURL;
31
+ token;
32
+ constructor(baseURL) {
33
+ this.baseURL = baseURL;
34
+ }
35
+ async init() {
36
+ this.context = await test.request.newContext({
37
+ baseURL: this.baseURL
38
+ });
39
+ }
40
+ async authenticate(email, password) {
41
+ if (!this.context) {
42
+ throw new Error("Client not initialized. Call init() first.");
43
+ }
44
+ const response = await this.context.post("/api/auth/signin/password", {
45
+ data: { email, password }
46
+ });
47
+ if (!response.ok()) {
48
+ const error = await response.text();
49
+ throw new Error(`Authentication failed: ${error}`);
50
+ }
51
+ const data = await response.json();
52
+ this.token = data.token;
53
+ return data;
54
+ }
55
+ async get(path, options) {
56
+ if (!this.context) {
57
+ throw new Error("Client not initialized. Call init() first.");
58
+ }
59
+ return this.context.get(path, {
60
+ headers: this.token ? { Authorization: `Bearer ${this.token}` } : {},
61
+ params: options?.params
62
+ });
63
+ }
64
+ async post(path, data) {
65
+ if (!this.context) {
66
+ throw new Error("Client not initialized. Call init() first.");
67
+ }
68
+ return this.context.post(path, {
69
+ data,
70
+ headers: this.token ? {
71
+ Authorization: `Bearer ${this.token}`,
72
+ "Content-Type": "application/json"
73
+ } : { "Content-Type": "application/json" }
74
+ });
75
+ }
76
+ async patch(path, data) {
77
+ if (!this.context) {
78
+ throw new Error("Client not initialized. Call init() first.");
79
+ }
80
+ return this.context.patch(path, {
81
+ data,
82
+ headers: this.token ? {
83
+ Authorization: `Bearer ${this.token}`,
84
+ "Content-Type": "application/json"
85
+ } : { "Content-Type": "application/json" }
86
+ });
87
+ }
88
+ async delete(path) {
89
+ if (!this.context) {
90
+ throw new Error("Client not initialized. Call init() first.");
91
+ }
92
+ return this.context.delete(path, {
93
+ headers: this.token ? { Authorization: `Bearer ${this.token}` } : {}
94
+ });
95
+ }
96
+ async dispose() {
97
+ if (this.context) {
98
+ await this.context.dispose();
99
+ this.context = null;
100
+ }
101
+ }
102
+ };
103
+ var scheduledJobFactory = {
104
+ build(overrides) {
105
+ return {
106
+ id: faker.faker.string.uuid(),
107
+ createPending: true,
108
+ name: faker.faker.lorem.words(3),
109
+ scheduleType: "tribe",
110
+ jobType: "post",
111
+ frequency: "daily",
112
+ schedule: [
113
+ {
114
+ time: "09:00",
115
+ postType: "post",
116
+ model: "sushi",
117
+ charLimit: 500,
118
+ credits: 10,
119
+ intervalMinutes: 60
120
+ }
121
+ ],
122
+ timezone: "Europe/Istanbul",
123
+ startDate: /* @__PURE__ */ new Date(),
124
+ totalCredits: 10,
125
+ totalPrice: 500,
126
+ 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: {},
135
+ ...overrides
136
+ };
137
+ },
138
+ buildMany(count, overrides) {
139
+ return Array.from({ length: count }, () => this.build(overrides));
140
+ }
141
+ };
142
+
25
143
  // src/index.ts
26
144
  dotenv__namespace.config();
27
145
  var TEST_GUEST_FINGERPRINTS = (process.env.TEST_GUEST_FINGERPRINTS?.split(",") || []).filter((fp) => fp);
@@ -133,6 +251,7 @@ var log = ({ page }) => {
133
251
  });
134
252
  };
135
253
 
254
+ exports.APIClient = APIClient;
136
255
  exports.TEST_GUEST_FINGERPRINTS = TEST_GUEST_FINGERPRINTS;
137
256
  exports.TEST_MEMBER_EMAILS = TEST_MEMBER_EMAILS;
138
257
  exports.TEST_MEMBER_FINGERPRINTS = TEST_MEMBER_FINGERPRINTS;
@@ -158,6 +277,7 @@ exports.getModelCredits = getModelCredits;
158
277
  exports.getURL = getURL;
159
278
  exports.isCI = isCI;
160
279
  exports.log = log;
280
+ exports.scheduledJobFactory = scheduledJobFactory;
161
281
  exports.simulateInputPaste = simulateInputPaste;
162
282
  exports.simulatePaste = simulatePaste;
163
283
  exports.storeApps = storeApps;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":["dotenv"],"mappings":"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","file":"index.js","sourcesContent":["import type { Page } from \"@playwright/test\"\nimport * as dotenv from \"dotenv\"\n\ndotenv.config()\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":"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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 Utilities\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
@@ -1,4 +1,122 @@
1
1
  import * as dotenv from 'dotenv';
2
+ import { request } from '@playwright/test';
3
+ import { faker } from '@faker-js/faker';
4
+
5
+ // src/index.ts
6
+ var APIClient = class {
7
+ context = null;
8
+ baseURL;
9
+ token;
10
+ constructor(baseURL) {
11
+ this.baseURL = baseURL;
12
+ }
13
+ async init() {
14
+ this.context = await request.newContext({
15
+ baseURL: this.baseURL
16
+ });
17
+ }
18
+ async authenticate(email, password) {
19
+ if (!this.context) {
20
+ throw new Error("Client not initialized. Call init() first.");
21
+ }
22
+ const response = await this.context.post("/api/auth/signin/password", {
23
+ data: { email, password }
24
+ });
25
+ if (!response.ok()) {
26
+ const error = await response.text();
27
+ throw new Error(`Authentication failed: ${error}`);
28
+ }
29
+ const data = await response.json();
30
+ this.token = data.token;
31
+ return data;
32
+ }
33
+ async get(path, options) {
34
+ if (!this.context) {
35
+ throw new Error("Client not initialized. Call init() first.");
36
+ }
37
+ return this.context.get(path, {
38
+ headers: this.token ? { Authorization: `Bearer ${this.token}` } : {},
39
+ params: options?.params
40
+ });
41
+ }
42
+ async post(path, data) {
43
+ if (!this.context) {
44
+ throw new Error("Client not initialized. Call init() first.");
45
+ }
46
+ return this.context.post(path, {
47
+ data,
48
+ headers: this.token ? {
49
+ Authorization: `Bearer ${this.token}`,
50
+ "Content-Type": "application/json"
51
+ } : { "Content-Type": "application/json" }
52
+ });
53
+ }
54
+ async patch(path, data) {
55
+ if (!this.context) {
56
+ throw new Error("Client not initialized. Call init() first.");
57
+ }
58
+ return this.context.patch(path, {
59
+ data,
60
+ headers: this.token ? {
61
+ Authorization: `Bearer ${this.token}`,
62
+ "Content-Type": "application/json"
63
+ } : { "Content-Type": "application/json" }
64
+ });
65
+ }
66
+ async delete(path) {
67
+ if (!this.context) {
68
+ throw new Error("Client not initialized. Call init() first.");
69
+ }
70
+ return this.context.delete(path, {
71
+ headers: this.token ? { Authorization: `Bearer ${this.token}` } : {}
72
+ });
73
+ }
74
+ async dispose() {
75
+ if (this.context) {
76
+ await this.context.dispose();
77
+ this.context = null;
78
+ }
79
+ }
80
+ };
81
+ var scheduledJobFactory = {
82
+ build(overrides) {
83
+ return {
84
+ id: faker.string.uuid(),
85
+ createPending: true,
86
+ name: faker.lorem.words(3),
87
+ scheduleType: "tribe",
88
+ jobType: "post",
89
+ frequency: "daily",
90
+ schedule: [
91
+ {
92
+ time: "09:00",
93
+ postType: "post",
94
+ model: "sushi",
95
+ charLimit: 500,
96
+ credits: 10,
97
+ intervalMinutes: 60
98
+ }
99
+ ],
100
+ timezone: "Europe/Istanbul",
101
+ startDate: /* @__PURE__ */ new Date(),
102
+ totalCredits: 10,
103
+ totalPrice: 500,
104
+ 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: {},
113
+ ...overrides
114
+ };
115
+ },
116
+ buildMany(count, overrides) {
117
+ return Array.from({ length: count }, () => this.build(overrides));
118
+ }
119
+ };
2
120
 
3
121
  // src/index.ts
4
122
  dotenv.config();
@@ -111,6 +229,6 @@ var log = ({ page }) => {
111
229
  });
112
230
  };
113
231
 
114
- export { TEST_GUEST_FINGERPRINTS, TEST_MEMBER_EMAILS, TEST_MEMBER_FINGERPRINTS, TEST_URL, VEX_LIVE_FINGERPRINT, VEX_LIVE_FINGERPRINTS, VEX_LIVE_FINGERPRINT_2, VEX_LIVE_FINGERPRINT_3, VEX_TEST_EMAIL, VEX_TEST_EMAIL_2, VEX_TEST_EMAIL_3, VEX_TEST_EMAIL_4, VEX_TEST_FINGERPRINT, VEX_TEST_FINGERPRINT_2, VEX_TEST_FINGERPRINT_3, VEX_TEST_FINGERPRINT_4, VEX_TEST_PASSWORD, VEX_TEST_PASSWORD_2, VEX_TEST_PASSWORD_3, VEX_TEST_PASSWORD_4, capitalizeFirstLetter, getModelCredits, getURL, isCI, log, simulateInputPaste, simulatePaste, storeApps, wait };
232
+ export { APIClient, TEST_GUEST_FINGERPRINTS, TEST_MEMBER_EMAILS, TEST_MEMBER_FINGERPRINTS, TEST_URL, VEX_LIVE_FINGERPRINT, VEX_LIVE_FINGERPRINTS, VEX_LIVE_FINGERPRINT_2, VEX_LIVE_FINGERPRINT_3, VEX_TEST_EMAIL, VEX_TEST_EMAIL_2, VEX_TEST_EMAIL_3, VEX_TEST_EMAIL_4, VEX_TEST_FINGERPRINT, VEX_TEST_FINGERPRINT_2, VEX_TEST_FINGERPRINT_3, VEX_TEST_FINGERPRINT_4, VEX_TEST_PASSWORD, VEX_TEST_PASSWORD_2, VEX_TEST_PASSWORD_3, VEX_TEST_PASSWORD_4, capitalizeFirstLetter, getModelCredits, getURL, isCI, log, scheduledJobFactory, simulateInputPaste, simulatePaste, storeApps, wait };
115
233
  //# sourceMappingURL=index.mjs.map
116
234
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import type { Page } from \"@playwright/test\"\nimport * as dotenv from \"dotenv\"\n\ndotenv.config()\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\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 Utilities\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.45",
3
+ "version": "2.3.47",
4
4
  "description": "Production-ready Playwright testing utilities and helpers for modern web apps",
5
5
  "keywords": [
6
6
  "automation",
@@ -45,7 +45,11 @@
45
45
  "ec": "pnpm exec playwright install chromium && playwright test critical.spec.ts --project chromium",
46
46
  "lint": "biome check .",
47
47
  "sync-goals": "tsx src/scripts/sync-plausible-goals.ts",
48
- "test:tauri": "TEST_URL=http://localhost:5173 playwright test --project tauri-macos"
48
+ "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"
49
53
  },
50
54
  "dependencies": {
51
55
  "@faker-js/faker": "^9.3.0",