Skip to content

Conversation

@cubic-dev-local
Copy link

@cubic-dev-local cubic-dev-local bot commented Sep 26, 2025

## Summary
  • Migrate basic folder tests to Playwright
  • Update pnpm to fix that annoying "time" bug
  • Add folder API + minor tests

Related Linear tickets, Github issues, and Community forum posts

Review / Merge checklist


Summary by cubic

Migrated basic folder tests to Playwright and added a folders API/helper to cover creation, navigation, and search. This improves test reliability and expands coverage for folder flows across projects.

  • New Features

    • Added folders API helper with create, update, delete, list, tree, and content endpoints.
    • Added navigation helper to visit folder routes.
    • Extended WorkflowsPage with folder actions (add via dropdown, breadcrumbs, header button, and card menu) and modal helpers.
    • New tests for folder creation paths, breadcrumb navigation across nested folders, and search from project root.
  • Refactors

    • Renamed ApiHelpers.projectApi to ApiHelpers.projects; updated usages.
    • Renamed WorkflowsPage.searchWorkflows to search.
    • Added TestEntryComposer.withProjectFeatures to enable required flags.
    • BasePage now exposes BaseModal for modal interactions.

@sanxroz
Copy link
Collaborator

sanxroz commented Sep 26, 2025

@cubic-dev-local review this

@cubic-dev-local
Copy link
Author

@cubic-dev-local review this

@sanxroz I've started the AI code review. It'll take a few minutes to complete.

Copy link
Author

@cubic-dev-local cubic-dev-local bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 issues found across 9 files

Prompt for AI agents (all 4 issues)

Understand the root cause of the following 4 issues and fix them.


<file name="packages/testing/playwright/pages/BasePage.ts">

<violation number="1" location="packages/testing/playwright/pages/BasePage.ts:6">
BaseModal is instantiated in a field initializer using `this.page` before the constructor parameter property is assigned, causing BaseModal to capture `undefined` under TS 5 field semantics and leading to runtime TypeErrors when modal methods access `page`.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Because the project targets ES2021, TypeScript emits class fields as constructor assignments after the parameter property assignment; therefore `new BaseModal(this.page)` receives the initialized `page` object and the alleged runtime error cannot occur.

• **Libraries consulted**: TypeScript useDefineForClassFields field initialization order, Typescript</violation>

<violation number="2" location="packages/testing/playwright/pages/BasePage.ts:6">
Adding `baseModal` to BasePage creates redundant BaseModal instances and duplicates the existing global `n8n.modal` access pattern, causing architectural inconsistency.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: `BaseModal` is a stateless helper that merely wraps Playwright selectors. Instantiating it inside `BasePage` gives derived pages convenient modal helpers without conflicting with or duplicating `n8n.modal`, so there’s no impactful issue to report.</violation>
</file>

<file name="packages/testing/playwright/services/api-helper.ts">

<violation number="1" location="packages/testing/playwright/services/api-helper.ts:39">
Naming inconsistency: `projects` was renamed while other API helper properties keep the `...Api` suffix, producing a mixed naming convention.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: typescriptUnderstanding, functionalImpact.*

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Renaming the property from `projectApi` to `projects` only affects naming style. The helper remains correctly typed and instantiated, keeping behavior unchanged. This stylistic mismatch doesn’t meet the bar for an actionable violation.</violation>
</file>

<file name="packages/testing/playwright/composables/TestEntryComposer.ts">

<violation number="1" location="packages/testing/playwright/composables/TestEntryComposer.ts:70">
`fromNewProject` now enables project features (folders, sharing) globally for any new-project test, expanding test setup scope and introducing side effects in unrelated tests.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Although `fromNewProject` now enables additional feature flags (`sharing`, `folders`, `advancedPermissions`), there is no evidence that this results in incorrect behavior or impacts unrelated tests. Without demonstrable negative impact, the issue is not severe enough to report.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

import { BaseModal } from './components/BaseModal';

export abstract class BasePage {
protected readonly baseModal = new BaseModal(this.page);
Copy link
Author

@cubic-dev-local cubic-dev-local bot Sep 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BaseModal is instantiated in a field initializer using this.page before the constructor parameter property is assigned, causing BaseModal to capture undefined under TS 5 field semantics and leading to runtime TypeErrors when modal methods access page.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: Because the project targets ES2021, TypeScript emits class fields as constructor assignments after the parameter property assignment; therefore new BaseModal(this.page) receives the initialized page object and the alleged runtime error cannot occur.

Libraries consulted: TypeScript useDefineForClassFields field initialization order, Typescript

Prompt for AI agents
Address the following comment on packages/testing/playwright/pages/BasePage.ts at line 6:

<comment>BaseModal is instantiated in a field initializer using `this.page` before the constructor parameter property is assigned, causing BaseModal to capture `undefined` under TS 5 field semantics and leading to runtime TypeErrors when modal methods access `page`.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Because the project targets ES2021, TypeScript emits class fields as constructor assignments after the parameter property assignment; therefore `new BaseModal(this.page)` receives the initialized `page` object and the alleged runtime error cannot occur.

• **Libraries consulted**: TypeScript useDefineForClassFields field initialization order, Typescript</comment>

<file context>
@@ -1,6 +1,9 @@
+import { BaseModal } from &#39;./components/BaseModal&#39;;
+
 export abstract class BasePage {
+	protected readonly baseModal = new BaseModal(this.page);
 	constructor(protected readonly page: Page) {}
 
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: Functional Bugs Agent

Fix with Cubic

request: APIRequestContext;
workflowApi: WorkflowApiHelper;
projectApi: ProjectApiHelper;
projects: ProjectApiHelper;
Copy link
Author

@cubic-dev-local cubic-dev-local bot Sep 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naming inconsistency: projects was renamed while other API helper properties keep the ...Api suffix, producing a mixed naming convention.

DEV MODE: This violation would have been filtered out by screening filters. Failing filters: typescriptUnderstanding, functionalImpact.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: Renaming the property from projectApi to projects only affects naming style. The helper remains correctly typed and instantiated, keeping behavior unchanged. This stylistic mismatch doesn’t meet the bar for an actionable violation.

Prompt for AI agents
Address the following comment on packages/testing/playwright/services/api-helper.ts at line 39:

<comment>Naming inconsistency: `projects` was renamed while other API helper properties keep the `...Api` suffix, producing a mixed naming convention.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: typescriptUnderstanding, functionalImpact.*

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Renaming the property from `projectApi` to `projects` only affects naming style. The helper remains correctly typed and instantiated, keeping behavior unchanged. This stylistic mismatch doesn’t meet the bar for an actionable violation.</comment>

<file context>
@@ -36,14 +36,14 @@ const DB_TAGS = {
 	request: APIRequestContext;
 	workflowApi: WorkflowApiHelper;
-	projectApi: ProjectApiHelper;
+	projects: ProjectApiHelper;
 	credentialApi: CredentialApiHelper;
 	variablesApi: VariablesApiHelper;
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: System Design Agent

Fix with Cubic

* Enable project feature set
* Allow project creation, sharing, and folder creation
*/
async withProjectFeatures() {
Copy link
Author

@cubic-dev-local cubic-dev-local bot Sep 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fromNewProject now enables project features (folders, sharing) globally for any new-project test, expanding test setup scope and introducing side effects in unrelated tests.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: Although fromNewProject now enables additional feature flags (sharing, folders, advancedPermissions), there is no evidence that this results in incorrect behavior or impacts unrelated tests. Without demonstrable negative impact, the issue is not severe enough to report.

Prompt for AI agents
Address the following comment on packages/testing/playwright/composables/TestEntryComposer.ts at line 70:

<comment>`fromNewProject` now enables project features (folders, sharing) globally for any new-project test, expanding test setup scope and introducing side effects in unrelated tests.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: Although `fromNewProject` now enables additional feature flags (`sharing`, `folders`, `advancedPermissions`), there is no evidence that this results in incorrect behavior or impacts unrelated tests. Without demonstrable negative impact, the issue is not severe enough to report.</comment>

<file context>
@@ -66,4 +62,17 @@ export class TestEntryComposer {
+	 * Enable project feature set
+	 * Allow project creation, sharing, and folder creation
+	 */
+	async withProjectFeatures() {
+		await this.n8n.api.enableFeature(&#39;sharing&#39;);
+		await this.n8n.api.enableFeature(&#39;folders&#39;);
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: System Design Agent

Fix with Cubic

import { BaseModal } from './components/BaseModal';

export abstract class BasePage {
protected readonly baseModal = new BaseModal(this.page);
Copy link
Author

@cubic-dev-local cubic-dev-local bot Sep 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding baseModal to BasePage creates redundant BaseModal instances and duplicates the existing global n8n.modal access pattern, causing architectural inconsistency.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: BaseModal is a stateless helper that merely wraps Playwright selectors. Instantiating it inside BasePage gives derived pages convenient modal helpers without conflicting with or duplicating n8n.modal, so there’s no impactful issue to report.

Prompt for AI agents
Address the following comment on packages/testing/playwright/pages/BasePage.ts at line 6:

<comment>Adding `baseModal` to BasePage creates redundant BaseModal instances and duplicates the existing global `n8n.modal` access pattern, causing architectural inconsistency.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: `BaseModal` is a stateless helper that merely wraps Playwright selectors. Instantiating it inside `BasePage` gives derived pages convenient modal helpers without conflicting with or duplicating `n8n.modal`, so there’s no impactful issue to report.</comment>

<file context>
@@ -1,6 +1,9 @@
+import { BaseModal } from &#39;./components/BaseModal&#39;;
+
 export abstract class BasePage {
+	protected readonly baseModal = new BaseModal(this.page);
 	constructor(protected readonly page: Page) {}
 
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: System Design Agent

Fix with Cubic

@sanxroz
Copy link
Collaborator

sanxroz commented Sep 26, 2025

@cubic-dev-local review this

@cubic-dev-local
Copy link
Author

@cubic-dev-local review this

@sanxroz I've started the AI code review. It'll take a few minutes to complete.

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 9 files

Prompt for AI agents (all 2 issues)

Understand the root cause of the following 2 issues and fix them.


<file name="packages/testing/playwright/helpers/NavigationHelper.ts">

<violation number="1" location="packages/testing/playwright/helpers/NavigationHelper.ts:129">
When `projectId` is omitted, `toFolder` navigates to `/folders/${folderId}/workflows`, but the router only exposes folder routes under `/home/folders/:folderId?/workflows`. Hitting `/folders/...` will miss the route and return 404. Prefix the global path with `/home` so global folder navigation works.</violation>
</file>

<file name="packages/testing/playwright/pages/BasePage.ts">

<violation number="1" location="packages/testing/playwright/pages/BasePage.ts:6">
Class field initializer constructs BaseModal with undefined this.page under TS 5.x define semantics, causing runtime errors when baseModal is used.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

async toFolder(folderId: string, projectId?: string): Promise<void> {
const url = projectId
? `/projects/${projectId}/folders/${folderId}/workflows`
: `/folders/${folderId}/workflows`;
Copy link

@cubic-dev-ai cubic-dev-ai bot Sep 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When projectId is omitted, toFolder navigates to /folders/${folderId}/workflows, but the router only exposes folder routes under /home/folders/:folderId?/workflows. Hitting /folders/... will miss the route and return 404. Prefix the global path with /home so global folder navigation works.

Prompt for AI agents
Address the following comment on packages/testing/playwright/helpers/NavigationHelper.ts at line 129:

<comment>When `projectId` is omitted, `toFolder` navigates to `/folders/${folderId}/workflows`, but the router only exposes folder routes under `/home/folders/:folderId?/workflows`. Hitting `/folders/...` will miss the route and return 404. Prefix the global path with `/home` so global folder navigation works.</comment>

<file context>
@@ -119,6 +119,17 @@ export class NavigationHelper {
+	async toFolder(folderId: string, projectId?: string): Promise&lt;void&gt; {
+		const url = projectId
+			? `/projects/${projectId}/folders/${folderId}/workflows`
+			: `/folders/${folderId}/workflows`;
+		await this.page.goto(url);
+	}
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: General AI Review Agent

Suggested change
: `/folders/${folderId}/workflows`;
: `/home/folders/${folderId}/workflows`;
Fix with Cubic

import { BaseModal } from './components/BaseModal';

export abstract class BasePage {
protected readonly baseModal = new BaseModal(this.page);
Copy link

@cubic-dev-ai cubic-dev-ai bot Sep 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Class field initializer constructs BaseModal with undefined this.page under TS 5.x define semantics, causing runtime errors when baseModal is used.

Prompt for AI agents
Address the following comment on packages/testing/playwright/pages/BasePage.ts at line 6:

<comment>Class field initializer constructs BaseModal with undefined this.page under TS 5.x define semantics, causing runtime errors when baseModal is used.</comment>

<file context>
@@ -1,6 +1,9 @@
+import { BaseModal } from &#39;./components/BaseModal&#39;;
+
 export abstract class BasePage {
+	protected readonly baseModal = new BaseModal(this.page);
 	constructor(protected readonly page: Page) {}
 
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: Functional Bugs Agent

Fix with Cubic

Copy link
Author

@cubic-dev-local cubic-dev-local bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 9 files

Prompt for AI agents (all 1 issues)

Understand the root cause of the following 1 issues and fix them.


<file name="packages/testing/playwright/pages/WorkflowsPage.ts">

<violation number="1" location="packages/testing/playwright/pages/WorkflowsPage.ts:167">
`getFolderBreadcrumbsAction` scopes the action lookup to the toggle element, but the dropdown menu renders outside that subtree, so the locator never resolves and clicking the action will fail. Please query the action from `page` (as done in `ResourceCards.getCardAction`).

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: `getFolderBreadcrumbsActionToggle()` already locates the teleported dropdown overlay (`data-test-id=&quot;action-toggle-dropdown&quot;`), so chaining `.getByTestId(�}action-${actionName}`�{)` reaches the menu items correctly despite the overlay being outside the toggle element hierarchy. The reported failure does not occur.

• **Libraries consulted**: Element Plus ElDropdown popper append to body, Element-plus</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

}

getFolderBreadcrumbsAction(actionName: string) {
return this.getFolderBreadcrumbsActionToggle().getByTestId(`action-${actionName}`);
Copy link
Author

@cubic-dev-local cubic-dev-local bot Sep 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getFolderBreadcrumbsAction scopes the action lookup to the toggle element, but the dropdown menu renders outside that subtree, so the locator never resolves and clicking the action will fail. Please query the action from page (as done in ResourceCards.getCardAction).

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: getFolderBreadcrumbsActionToggle() already locates the teleported dropdown overlay (data-test-id="action-toggle-dropdown"), so chaining .getByTestId(�}action-${actionName}�{)` reaches the menu items correctly despite the overlay being outside the toggle element hierarchy. The reported failure does not occur.

Libraries consulted: Element Plus ElDropdown popper append to body, Element-plus

Prompt for AI agents
Address the following comment on packages/testing/playwright/pages/WorkflowsPage.ts at line 167:

<comment>`getFolderBreadcrumbsAction` scopes the action lookup to the toggle element, but the dropdown menu renders outside that subtree, so the locator never resolves and clicking the action will fail. Please query the action from `page` (as done in `ResourceCards.getCardAction`).

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: `getFolderBreadcrumbsActionToggle()` already locates the teleported dropdown overlay (`data-test-id=&quot;action-toggle-dropdown&quot;`), so chaining `.getByTestId(�}action-${actionName}`�{)` reaches the menu items correctly despite the overlay being outside the toggle element hierarchy. The reported failure does not occur.

• **Libraries consulted**: Element Plus ElDropdown popper append to body, Element-plus</comment>

<file context>
@@ -154,4 +154,42 @@ export class WorkflowsPage extends BasePage {
+	}
+
+	getFolderBreadcrumbsAction(actionName: string) {
+		return this.getFolderBreadcrumbsActionToggle().getByTestId(`action-${actionName}`);
+	}
+
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: General AI Review Agent

Suggested change
return this.getFolderBreadcrumbsActionToggle().getByTestId(`action-${actionName}`);
return this.page.getByTestId(`action-${actionName}`);
Fix with Cubic

@sanxroz
Copy link
Collaborator

sanxroz commented Sep 26, 2025

@cubic-dev-local review this

@cubic-dev-local
Copy link
Author

@cubic-dev-local review this

@sanxroz I've started the AI code review. It'll take a few minutes to complete.

Copy link
Author

@cubic-dev-local cubic-dev-local bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 9 files

@sanxroz
Copy link
Collaborator

sanxroz commented Sep 26, 2025

@cubic-dev-local review this

@cubic-dev-local
Copy link
Author

@cubic-dev-local review this

@sanxroz I've started the AI code review. It'll take a few minutes to complete.

Copy link
Author

@cubic-dev-local cubic-dev-local bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 9 files

Prompt for AI agents (all 1 issues)

Understand the root cause of the following 1 issues and fix them.


<file name="packages/testing/playwright/pages/BasePage.ts">

<violation number="1" location="packages/testing/playwright/pages/BasePage.ts:6">
Class field initializer uses this.page before it’s assigned, constructing BaseModal with undefined and causing runtime errors when baseModal is used.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

import { BaseModal } from './components/BaseModal';

export abstract class BasePage {
protected readonly baseModal = new BaseModal(this.page);
Copy link
Author

@cubic-dev-local cubic-dev-local bot Sep 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Class field initializer uses this.page before it’s assigned, constructing BaseModal with undefined and causing runtime errors when baseModal is used.

Prompt for AI agents
Address the following comment on packages/testing/playwright/pages/BasePage.ts at line 6:

<comment>Class field initializer uses this.page before it’s assigned, constructing BaseModal with undefined and causing runtime errors when baseModal is used.</comment>

<file context>
@@ -1,6 +1,9 @@
+import { BaseModal } from &#39;./components/BaseModal&#39;;
+
 export abstract class BasePage {
+	protected readonly baseModal = new BaseModal(this.page);
 	constructor(protected readonly page: Page) {}
 
</file context>

[internal] Confidence score: 8/10

[internal] Posted by: Functional Bugs Agent

Fix with Cubic

@sanxroz
Copy link
Collaborator

sanxroz commented Oct 2, 2025

@cubic-dev-local review this

@cubic-dev-local
Copy link
Author

@cubic-dev-local review this

@sanxroz I've started the AI code review. It'll take a few minutes to complete.

Copy link
Author

@cubic-dev-local cubic-dev-local bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 9 files

Prompt for AI agents (all 2 issues)

Understand the root cause of the following 2 issues and fix them.


<file name="packages/testing/playwright/services/project-api-helper.ts">

<violation number="1" location="packages/testing/playwright/services/project-api-helper.ts:131">
Folder tree retrieval logic duplicates `packages/frontend/editor-ui/src/api/workflows.ts:getFolderPath()` function. The semantic purpose and API endpoint used are identical. Reusing the existing function would centralize API logic.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: The Playwright helper depends on the testing runtime’s ApiHelpers.request abstraction, while the frontend function relies on IRestApiContext and makeRestApiRequest. Because these live in different environments with incompatible infrastructure, consolidating them isn’t realistic, so the duplication isn’t actionable.</violation>

<violation number="2" location="packages/testing/playwright/services/project-api-helper.ts:172">
Folder content retrieval logic duplicates `packages/frontend/editor-ui/src/api/workflows.ts:getFolderContent()` function. The semantic purpose and API endpoint used are identical. Reusing the existing function would centralize API logic.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: typescriptUnderstanding.*

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: This Playwright helper also uses ApiHelpers.request in the test runtime, whereas the frontend counterpart uses IRestApiContext/getFullApiResponse. The divergent runtimes make code sharing impractical, rendering the duplication low-impact and not worth flagging.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

* @param folderId The ID of the folder
* @returns Folder content counts
*/
async getFolderContent(projectId: string, folderId: string) {
Copy link
Author

@cubic-dev-local cubic-dev-local bot Oct 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Folder content retrieval logic duplicates packages/frontend/editor-ui/src/api/workflows.ts:getFolderContent() function. The semantic purpose and API endpoint used are identical. Reusing the existing function would centralize API logic.

DEV MODE: This violation would have been filtered out by screening filters. Failing filters: typescriptUnderstanding.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: This Playwright helper also uses ApiHelpers.request in the test runtime, whereas the frontend counterpart uses IRestApiContext/getFullApiResponse. The divergent runtimes make code sharing impractical, rendering the duplication low-impact and not worth flagging.

Prompt for AI agents
Address the following comment on packages/testing/playwright/services/project-api-helper.ts at line 172:

<comment>Folder content retrieval logic duplicates `packages/frontend/editor-ui/src/api/workflows.ts:getFolderContent()` function. The semantic purpose and API endpoint used are identical. Reusing the existing function would centralize API logic.

*DEV MODE: This violation would have been filtered out by screening filters. Failing filters: typescriptUnderstanding.*

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: This Playwright helper also uses ApiHelpers.request in the test runtime, whereas the frontend counterpart uses IRestApiContext/getFullApiResponse. The divergent runtimes make code sharing impractical, rendering the duplication low-impact and not worth flagging.</comment>

<file context>
@@ -42,4 +43,142 @@ export class ProjectApiHelper {
+	 * @param folderId The ID of the folder
+	 * @returns Folder content counts
+	 */
+	async getFolderContent(projectId: string, folderId: string) {
+		const response = await this.api.request.get(
+			`/rest/projects/${projectId}/folders/${folderId}/content`,
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: Duplicate Detection Agent

Fix with Cubic

* @param folderId The ID of the folder to get the tree for
* @returns The folder tree data
*/
async getFolderTree(projectId: string, folderId: string) {
Copy link
Author

@cubic-dev-local cubic-dev-local bot Oct 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Folder tree retrieval logic duplicates packages/frontend/editor-ui/src/api/workflows.ts:getFolderPath() function. The semantic purpose and API endpoint used are identical. Reusing the existing function would centralize API logic.

    DEV MODE: This violation would have been filtered out by GPT-5.

Reasoning:
GPT-5: The Playwright helper depends on the testing runtime’s ApiHelpers.request abstraction, while the frontend function relies on IRestApiContext and makeRestApiRequest. Because these live in different environments with incompatible infrastructure, consolidating them isn’t realistic, so the duplication isn’t actionable.

Prompt for AI agents
Address the following comment on packages/testing/playwright/services/project-api-helper.ts at line 131:

<comment>Folder tree retrieval logic duplicates `packages/frontend/editor-ui/src/api/workflows.ts:getFolderPath()` function. The semantic purpose and API endpoint used are identical. Reusing the existing function would centralize API logic.

        DEV MODE: This violation would have been filtered out by GPT-5.
Reasoning:
• **GPT-5**: The Playwright helper depends on the testing runtime’s ApiHelpers.request abstraction, while the frontend function relies on IRestApiContext and makeRestApiRequest. Because these live in different environments with incompatible infrastructure, consolidating them isn’t realistic, so the duplication isn’t actionable.</comment>

<file context>
@@ -42,4 +43,142 @@ export class ProjectApiHelper {
+	 * @param folderId The ID of the folder to get the tree for
+	 * @returns The folder tree data
+	 */
+	async getFolderTree(projectId: string, folderId: string) {
+		const response = await this.api.request.get(
+			`/rest/projects/${projectId}/folders/${folderId}/tree`,
</file context>

[internal] Confidence score: 9/10

[internal] Posted by: Duplicate Detection Agent

Fix with Cubic

@sanxroz
Copy link
Collaborator

sanxroz commented Oct 3, 2025

@cubic-dev-local review this

@cubic-dev-local
Copy link
Author

@cubic-dev-local review this

@sanxroz I've started the AI code review. It'll take a few minutes to complete.

1 similar comment
@cubic-dev-local
Copy link
Author

@cubic-dev-local review this

@sanxroz I've started the AI code review. It'll take a few minutes to complete.

Copy link
Author

@cubic-dev-local cubic-dev-local bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 9 files

Copy link
Author

@cubic-dev-local cubic-dev-local bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 9 files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants