-
Notifications
You must be signed in to change notification settings - Fork 0
test: Migrate basic folder tests to Playwright #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: eval-pr-20074-target-1758921939688
Are you sure you want to change the base?
test: Migrate basic folder tests to Playwright #4
Conversation
|
@cubic-dev-local review this |
@sanxroz I've started the AI code review. It'll take a few minutes to complete. |
There was a problem hiding this 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); |
There was a problem hiding this comment.
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 './components/BaseModal';
+
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
| request: APIRequestContext; | ||
| workflowApi: WorkflowApiHelper; | ||
| projectApi: ProjectApiHelper; | ||
| projects: ProjectApiHelper; |
There was a problem hiding this comment.
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
| * Enable project feature set | ||
| * Allow project creation, sharing, and folder creation | ||
| */ | ||
| async withProjectFeatures() { |
There was a problem hiding this comment.
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('sharing');
+ await this.n8n.api.enableFeature('folders');
</file context>
[internal] Confidence score: 9/10
[internal] Posted by: System Design Agent
| import { BaseModal } from './components/BaseModal'; | ||
|
|
||
| export abstract class BasePage { | ||
| protected readonly baseModal = new BaseModal(this.page); |
There was a problem hiding this comment.
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 './components/BaseModal';
+
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
|
@cubic-dev-local review this |
@sanxroz I've started the AI code review. It'll take a few minutes to complete. |
There was a problem hiding this 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`; |
There was a problem hiding this comment.
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<void> {
+ 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
| : `/folders/${folderId}/workflows`; | |
| : `/home/folders/${folderId}/workflows`; |
| import { BaseModal } from './components/BaseModal'; | ||
|
|
||
| export abstract class BasePage { | ||
| protected readonly baseModal = new BaseModal(this.page); |
There was a problem hiding this comment.
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 './components/BaseModal';
+
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
There was a problem hiding this 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="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</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}`); |
There was a problem hiding this comment.
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="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</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
| return this.getFolderBreadcrumbsActionToggle().getByTestId(`action-${actionName}`); | |
| return this.page.getByTestId(`action-${actionName}`); |
|
@cubic-dev-local review this |
@sanxroz I've started the AI code review. It'll take a few minutes to complete. |
There was a problem hiding this 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
|
@cubic-dev-local review this |
@sanxroz I've started the AI code review. It'll take a few minutes to complete. |
There was a problem hiding this 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); |
There was a problem hiding this comment.
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 './components/BaseModal';
+
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
|
@cubic-dev-local review this |
@sanxroz I've started the AI code review. It'll take a few minutes to complete. |
There was a problem hiding this 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) { |
There was a problem hiding this comment.
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
| * @param folderId The ID of the folder to get the tree for | ||
| * @returns The folder tree data | ||
| */ | ||
| async getFolderTree(projectId: string, folderId: string) { |
There was a problem hiding this comment.
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
|
@cubic-dev-local review this |
@sanxroz I've started the AI code review. It'll take a few minutes to complete. |
1 similar comment
@sanxroz I've started the AI code review. It'll take a few minutes to complete. |
There was a problem hiding this 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
There was a problem hiding this 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
Related Linear tickets, Github issues, and Community forum posts
Review / Merge checklist
PR title and summary are descriptive. (conventions)
Docs updated or follow-up ticket created.
Tests included.
PR Labeled with
release/backport(if the PR is an urgent fix that needs to be backported)Based on: test: Migrate basic folder tests to Playwright n8n-io/n8n#20074
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
Refactors