-
Notifications
You must be signed in to change notification settings - Fork 107
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix editor state and operation handling in Laboratory + e2e tests (#6282
) Fixes When opening a new tab or selecting one of the saved operations a wrong query was populated. It was always the default query or the one that's active. Meaning, you couldn't select and see the saved operation :) When saving the operation, the submit button of the form was always disabled, even when the state of the form was valid. e2e tests Added tests for CRUD of collections and their operations. The scenario where a user visits a shared link to an operation is also now tested.
- Loading branch information
1 parent
469443b
commit a7f9d50
Showing
14 changed files
with
350 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
--- | ||
'hive': patch | ||
--- | ||
|
||
Fix editor state and operation handling in Laboratory. | ||
|
||
When opening a new tab or selecting a saved operation, the editor incorrectly populated the query, defaulting to the active query. This made it impossible to view the selected operation. Additionally, the submit button for saving an operation was always disabled, even when the form was in a valid state. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,248 @@ | ||
import { laboratory } from '../support/testkit'; | ||
|
||
beforeEach(() => { | ||
cy.clearAllLocalStorage().then(() => { | ||
return cy.task('seedTarget').then(({ slug, refreshToken }: any) => { | ||
cy.setCookie('sRefreshToken', refreshToken); | ||
|
||
cy.visit(`/${slug}/laboratory`); | ||
|
||
// To make sure the operation collections tab is opened | ||
// It first opens the Documentation Explorer or GraphiQL Explorer, | ||
// then opens the Operation Collections tab. | ||
// It does that, because the Operation Collections tab could be already opened for some reason. | ||
// This way it's guaranteed that the Operation Collections tab is opened. | ||
cy.get('[aria-label*="Show Documentation Explorer"], [aria-label*="Show GraphiQL Explorer"]') | ||
.first() | ||
.click(); | ||
cy.get('[aria-label="Show Operation Collections"]').click(); | ||
}); | ||
}); | ||
}); | ||
|
||
const collections = { | ||
/** | ||
* Opens the modal to create a new collection and fills the form | ||
*/ | ||
create(args: { name: string; description: string }) { | ||
cy.get('button[data-cy="new-collection"]').click(); | ||
cy.get('div[data-cy="create-collection-modal"] input[name="name"]').type(args.name); | ||
cy.get('div[data-cy="create-collection-modal"] input[name="description"]').type( | ||
args.description, | ||
); | ||
cy.get('div[data-cy="create-collection-modal"] button[type="submit"]').click(); | ||
}, | ||
/** | ||
* Clicks on a collection in the sidebar | ||
*/ | ||
clickCollectionButton(name: string) { | ||
cy.get('button[data-cy="collection-item-trigger"]').contains(name).click(); | ||
}, | ||
/** | ||
* Saves the current operation as a new operation and assigns it to a collection | ||
*/ | ||
saveCurrentOperationAs(args: { name: string; collectionName: string }) { | ||
cy.get('[data-cy="save-operation"]').click(); | ||
cy.get('[data-cy="save-operation-as"]').click(); | ||
|
||
cy.get('div[data-cy="create-operation-modal"] input[name="name"]').type(args.name); | ||
cy.get( | ||
'div[data-cy="create-operation-modal"] button[data-cy="collection-select-trigger"]', | ||
).click(); | ||
|
||
cy.get('div[data-cy="collection-select-item"]').contains(args.collectionName).click(); | ||
cy.get('div[data-cy="create-operation-modal"] button[type="submit"]').click(); | ||
}, | ||
/** | ||
* Opens the menu for a specific operation, to access delete, copy link or edit buttons. | ||
*/ | ||
openOperationMenu(name: string) { | ||
return cy.get(`a[data-cy="operation-${name}"] ~ button`).click(); | ||
}, | ||
/** | ||
* Opens the menu for a specific collection, to access delete or edit buttons. | ||
*/ | ||
openCollectionMenu(name: string) { | ||
return cy | ||
.contains(`[data-cy="collection-item-trigger"]`, name) | ||
.parent() | ||
.get('[data-cy="collection-menu-trigger"]') | ||
.click(); | ||
}, | ||
/** | ||
* Returns the operation element | ||
*/ | ||
getOperationButton(name: string) { | ||
return cy.get<HTMLAnchorElement>(`a[data-cy="operation-${name}"]`); | ||
}, | ||
/** | ||
* Returns the collection element | ||
*/ | ||
getCollectionButton(name: string) { | ||
return cy.contains('[data-cy="collection-item"]', name); | ||
}, | ||
}; | ||
|
||
describe('Laboratory > Collections', () => { | ||
it('create a collection and an operation', () => { | ||
collections.create({ | ||
name: 'collection-1', | ||
description: 'Description 1', | ||
}); | ||
laboratory.updateEditorValue(`query op1 { test }`); | ||
collections.saveCurrentOperationAs({ | ||
name: 'operation-1', | ||
collectionName: 'collection-1', | ||
}); | ||
collections.getOperationButton('operation-1').should('exist'); | ||
}); | ||
|
||
it(`edit collection's name`, () => { | ||
collections.create({ | ||
name: 'collection-1', | ||
description: 'Description 1', | ||
}); | ||
laboratory.updateEditorValue(`query op1 { test }`); | ||
collections.saveCurrentOperationAs({ | ||
name: 'operation-1', | ||
collectionName: 'collection-1', | ||
}); | ||
|
||
collections.openCollectionMenu('collection-1'); | ||
// Click on the edit button and fill the form | ||
cy.get('[data-cy="edit-collection"]').click(); | ||
cy.get('[data-cy="create-collection-modal"]').should('exist'); | ||
cy.get('[data-cy="create-collection-modal"] input[name="name"]') | ||
.clear() | ||
.type('collection-1-updated'); | ||
cy.get('[data-cy="create-collection-modal"] button[data-cy="confirm"]').click(); | ||
|
||
collections.getCollectionButton('collection-1-updated').should('exist'); | ||
collections.getOperationButton('operation-1').should('exist'); | ||
}); | ||
|
||
it('delete a collection', () => { | ||
collections.create({ | ||
name: 'collection-1', | ||
description: 'Description 1', | ||
}); | ||
laboratory.updateEditorValue(`query op1 { test }`); | ||
collections.saveCurrentOperationAs({ | ||
name: 'operation-1', | ||
collectionName: 'collection-1', | ||
}); | ||
|
||
collections.getOperationButton('operation-1').should('exist'); | ||
collections.getCollectionButton('collection-1').should('exist'); | ||
|
||
collections.openCollectionMenu('collection-1'); | ||
// Click on the delete button and confirm the deletion | ||
cy.get('[data-cy="delete-collection"]').click(); | ||
cy.get('[data-cy="delete-collection-modal"]').should('exist'); | ||
cy.get('[data-cy="delete-collection-modal"] button[data-cy="confirm"]').click(); | ||
|
||
collections.getOperationButton('operation-1').should('not.exist'); | ||
collections.getCollectionButton('collection-1').should('not.exist'); | ||
}); | ||
|
||
it(`edit operation's name`, () => { | ||
collections.create({ | ||
name: 'collection-1', | ||
description: 'Description 1', | ||
}); | ||
laboratory.updateEditorValue(`query op1 { test }`); | ||
collections.saveCurrentOperationAs({ | ||
name: 'operation-1', | ||
collectionName: 'collection-1', | ||
}); | ||
|
||
collections.openOperationMenu('operation-1'); | ||
// Click on the edit button and fill the form | ||
cy.get('[data-cy="edit-operation"]').click(); | ||
cy.get('[data-cy="edit-operation-modal"]').should('exist'); | ||
cy.get('[data-cy="edit-operation-modal"] input[name="name"]').type('operation-1-updated'); | ||
cy.get('[data-cy="edit-operation-modal"] button[data-cy="confirm"]').click(); | ||
|
||
collections.getOperationButton('operation-1').should('not.exist'); | ||
collections.getOperationButton('operation-1-updated').should('exist'); | ||
}); | ||
|
||
it('delete an operation', () => { | ||
collections.create({ | ||
name: 'collection-1', | ||
description: 'Description 1', | ||
}); | ||
laboratory.updateEditorValue(`query op1 { test }`); | ||
collections.saveCurrentOperationAs({ | ||
name: 'operation-1', | ||
collectionName: 'collection-1', | ||
}); | ||
|
||
laboratory.openNewTab(); | ||
laboratory.updateEditorValue(`query op2 { test }`); | ||
collections.saveCurrentOperationAs({ | ||
name: 'operation-2', | ||
collectionName: 'collection-1', | ||
}); | ||
|
||
collections.openOperationMenu('operation-1'); | ||
// Click on the delete button and confirm the deletion | ||
cy.get('[data-cy="delete-operation"]').click(); | ||
cy.get('[data-cy="delete-operation-modal"]').should('exist'); | ||
cy.get('[data-cy="delete-operation-modal"] button[data-cy="confirm"]').click(); | ||
|
||
collections.getOperationButton('operation-1').should('not.exist'); | ||
collections.getOperationButton('operation-2').should('exist'); | ||
}); | ||
|
||
it('visiting a copied operation link should open the operation', () => { | ||
collections.create({ | ||
name: 'collection-1', | ||
description: 'Description 1', | ||
}); | ||
collections.create({ | ||
name: 'collection-2', | ||
description: 'Description 2', | ||
}); | ||
collections.clickCollectionButton('collection-1'); | ||
laboratory.updateEditorValue(`query op1 { test }`); | ||
collections.saveCurrentOperationAs({ | ||
name: 'operation-1', | ||
collectionName: 'collection-1', | ||
}); | ||
|
||
laboratory.openNewTab(); | ||
laboratory.updateEditorValue(`query op2 { test }`); | ||
collections.saveCurrentOperationAs({ | ||
name: 'operation-2', | ||
collectionName: 'collection-2', | ||
}); | ||
|
||
collections.openOperationMenu('operation-1'); | ||
|
||
// Stub the clipboard API to intercept the copied URL | ||
cy.window().then(win => { | ||
cy.stub(win.navigator.clipboard, 'writeText').as('copied'); | ||
}); | ||
|
||
cy.get('[data-cy="copy-operation-link"]').click(); | ||
|
||
cy.get<{ | ||
getCall(index: number): { | ||
args: unknown[]; | ||
}; | ||
}>('@copied') | ||
.should('have.been.calledOnce') | ||
.then(stub => { | ||
const copiedUrl = stub.getCall(0).args[0]; // Extract the copied URL | ||
if (typeof copiedUrl !== 'string') { | ||
throw new Error('The copied URL is not a string'); | ||
} | ||
// Navigate to the copied URL | ||
return cy.visit(copiedUrl); | ||
}); | ||
|
||
laboratory.assertActiveTab('operation-1'); | ||
laboratory.getEditorValue().should('contain', 'op1'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.