mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-12 21:37:32 -08:00
feat: Add workflow and credential sharing access e2e tests (#5463)
feat: add workflow and credential sharing access e2e tests
This commit is contained in:
parent
b25c10a0e1
commit
246189f6da
168
cypress/e2e/17-sharing.cy.ts
Normal file
168
cypress/e2e/17-sharing.cy.ts
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
import { DEFAULT_USER_EMAIL, DEFAULT_USER_PASSWORD } from '../constants';
|
||||||
|
import {
|
||||||
|
CredentialsModal,
|
||||||
|
CredentialsPage,
|
||||||
|
NDV,
|
||||||
|
WorkflowPage,
|
||||||
|
WorkflowSharingModal,
|
||||||
|
WorkflowsPage,
|
||||||
|
} from '../pages';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User U1 - Instance owner
|
||||||
|
* User U2 - User, owns C1, W1, W2
|
||||||
|
* User U3 - User, owns C2
|
||||||
|
*
|
||||||
|
* W1 - Workflow owned by User U2, shared with User U3
|
||||||
|
* W2 - Workflow owned by User U2
|
||||||
|
*
|
||||||
|
* C1 - Credential owned by User U2
|
||||||
|
* C2 - Credential owned by User U3, shared with User U1 and User U2
|
||||||
|
*/
|
||||||
|
|
||||||
|
const credentialsPage = new CredentialsPage();
|
||||||
|
const credentialsModal = new CredentialsModal();
|
||||||
|
|
||||||
|
const workflowsPage = new WorkflowsPage();
|
||||||
|
const workflowPage = new WorkflowPage();
|
||||||
|
const workflowSharingModal = new WorkflowSharingModal();
|
||||||
|
const ndv = new NDV();
|
||||||
|
|
||||||
|
const instanceOwner = {
|
||||||
|
email: `${DEFAULT_USER_EMAIL}one`,
|
||||||
|
password: DEFAULT_USER_PASSWORD,
|
||||||
|
firstName: 'User',
|
||||||
|
lastName: 'U1',
|
||||||
|
};
|
||||||
|
|
||||||
|
const users = [
|
||||||
|
{
|
||||||
|
email: `${DEFAULT_USER_EMAIL}two`,
|
||||||
|
password: DEFAULT_USER_PASSWORD,
|
||||||
|
firstName: 'User',
|
||||||
|
lastName: 'U2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
email: `${DEFAULT_USER_EMAIL}three`,
|
||||||
|
password: DEFAULT_USER_PASSWORD,
|
||||||
|
firstName: 'User',
|
||||||
|
lastName: 'U3',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
describe('Sharing', () => {
|
||||||
|
before(() => {
|
||||||
|
cy.resetAll();
|
||||||
|
cy.setupOwner(instanceOwner);
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.on('uncaught:exception', (err, runnable) => {
|
||||||
|
expect(err.message).to.include('Not logged in');
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should invite User U2 and User U3 to instance', () => {
|
||||||
|
cy.inviteUsers({ instanceOwner, users });
|
||||||
|
});
|
||||||
|
|
||||||
|
let workflowW2Url = '';
|
||||||
|
it('should create C1, W1, W2, share W1 with U3, as U2', () => {
|
||||||
|
cy.signin(users[0]);
|
||||||
|
|
||||||
|
cy.visit(credentialsPage.url);
|
||||||
|
credentialsPage.getters.emptyListCreateCredentialButton().click();
|
||||||
|
credentialsModal.getters.newCredentialTypeOption('Notion API').click();
|
||||||
|
credentialsModal.getters.newCredentialTypeButton().click();
|
||||||
|
credentialsModal.getters.connectionParameter('API Key').type('1234567890');
|
||||||
|
credentialsModal.actions.setName('Credential C1');
|
||||||
|
credentialsModal.actions.save();
|
||||||
|
credentialsModal.actions.close();
|
||||||
|
|
||||||
|
cy.visit(workflowsPage.url);
|
||||||
|
workflowsPage.getters.newWorkflowButtonCard().click();
|
||||||
|
workflowPage.actions.setWorkflowName('Workflow W1');
|
||||||
|
workflowPage.actions.addInitialNodeToCanvas('Manual Trigger');
|
||||||
|
workflowPage.actions.addNodeToCanvas('Notion', true, true);
|
||||||
|
ndv.getters.credentialInput().should('contain', 'Credential C1');
|
||||||
|
ndv.actions.close();
|
||||||
|
|
||||||
|
workflowPage.actions.openShareModal();
|
||||||
|
workflowSharingModal.actions.addUser(users[1].email);
|
||||||
|
workflowSharingModal.actions.save();
|
||||||
|
workflowPage.actions.saveWorkflowOnButtonClick();
|
||||||
|
|
||||||
|
cy.visit(workflowsPage.url);
|
||||||
|
workflowsPage.getters.createWorkflowButton().click();
|
||||||
|
cy.createFixtureWorkflow('Test_workflow_1.json', 'Workflow W2');
|
||||||
|
cy.url().then((url) => {
|
||||||
|
workflowW2Url = url;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create C2, share C2 with U1 and U2, as U3', () => {
|
||||||
|
cy.signin(users[1]);
|
||||||
|
|
||||||
|
cy.visit(credentialsPage.url);
|
||||||
|
credentialsPage.getters.emptyListCreateCredentialButton().click();
|
||||||
|
credentialsModal.getters.newCredentialTypeOption('Airtable API').click();
|
||||||
|
credentialsModal.getters.newCredentialTypeButton().click();
|
||||||
|
credentialsModal.getters.connectionParameter('API Key').type('1234567890');
|
||||||
|
credentialsModal.actions.setName('Credential C2');
|
||||||
|
credentialsModal.actions.changeTab('Sharing');
|
||||||
|
credentialsModal.actions.addUser(instanceOwner.email);
|
||||||
|
credentialsModal.actions.addUser(users[0].email);
|
||||||
|
credentialsModal.actions.save();
|
||||||
|
credentialsModal.actions.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should open W1, add node using C2 as U3', () => {
|
||||||
|
cy.signin(users[1]);
|
||||||
|
|
||||||
|
cy.visit(workflowsPage.url);
|
||||||
|
workflowsPage.getters.workflowCards().should('have.length', 1);
|
||||||
|
workflowsPage.getters.workflowCard('Workflow W1').click();
|
||||||
|
workflowPage.actions.addNodeToCanvas('Airtable', true, true);
|
||||||
|
ndv.getters.credentialInput().should('contain', 'Credential C2');
|
||||||
|
ndv.actions.close();
|
||||||
|
workflowPage.actions.saveWorkflowOnButtonClick();
|
||||||
|
|
||||||
|
workflowPage.actions.openNode('Notion');
|
||||||
|
ndv.getters
|
||||||
|
.credentialInput()
|
||||||
|
.find('input')
|
||||||
|
.should('have.value', 'Credential C1')
|
||||||
|
.should('be.disabled');
|
||||||
|
ndv.actions.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not have access to W2, as U3', () => {
|
||||||
|
cy.signin(users[1]);
|
||||||
|
|
||||||
|
cy.visit(workflowW2Url);
|
||||||
|
cy.waitForLoad();
|
||||||
|
cy.wait(1000);
|
||||||
|
cy.get('.el-notification').contains('Could not find workflow').should('be.visible');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have access to W1, W2, as U1', () => {
|
||||||
|
cy.signin(instanceOwner);
|
||||||
|
|
||||||
|
cy.visit(workflowsPage.url);
|
||||||
|
workflowsPage.getters.workflowCards().should('have.length', 2);
|
||||||
|
workflowsPage.getters.workflowCard('Workflow W1').click();
|
||||||
|
workflowPage.actions.openNode('Notion');
|
||||||
|
ndv.getters
|
||||||
|
.credentialInput()
|
||||||
|
.find('input')
|
||||||
|
.should('have.value', 'Credential C1')
|
||||||
|
.should('be.disabled');
|
||||||
|
ndv.actions.close();
|
||||||
|
|
||||||
|
cy.waitForLoad();
|
||||||
|
cy.visit(workflowsPage.url);
|
||||||
|
workflowsPage.getters.workflowCard('Workflow W2').click();
|
||||||
|
workflowPage.actions.executeWorkflow();
|
||||||
|
});
|
||||||
|
});
|
|
@ -26,8 +26,19 @@ export class CredentialsModal extends BasePage {
|
||||||
credentialAuthTypeRadioButtons: () =>
|
credentialAuthTypeRadioButtons: () =>
|
||||||
this.getters.credentialsAuthTypeSelector().find('label[role=radio]'),
|
this.getters.credentialsAuthTypeSelector().find('label[role=radio]'),
|
||||||
credentialInputs: () => cy.getByTestId('credential-connection-parameter'),
|
credentialInputs: () => cy.getByTestId('credential-connection-parameter'),
|
||||||
|
menu: () => this.getters.editCredentialModal().get('.menu-container'),
|
||||||
|
menuItem: (name: string) => this.getters.menu().get('.n8n-menu-item').contains(name),
|
||||||
|
usersSelect: () => cy.getByTestId('credential-sharing-modal-users-select'),
|
||||||
};
|
};
|
||||||
actions = {
|
actions = {
|
||||||
|
addUser: (email: string) => {
|
||||||
|
this.getters.usersSelect().click();
|
||||||
|
this.getters
|
||||||
|
.usersSelect()
|
||||||
|
.get('.el-select-dropdown__item')
|
||||||
|
.contains(email.toLowerCase())
|
||||||
|
.click();
|
||||||
|
},
|
||||||
setName: (name: string) => {
|
setName: (name: string) => {
|
||||||
this.getters.name().click();
|
this.getters.name().click();
|
||||||
this.getters.nameInput().clear().type(name);
|
this.getters.nameInput().clear().type(name);
|
||||||
|
@ -64,5 +75,8 @@ export class CredentialsModal extends BasePage {
|
||||||
this.getters.nameInput().type(newName);
|
this.getters.nameInput().type(newName);
|
||||||
this.getters.nameInput().type('{enter}');
|
this.getters.nameInput().type('{enter}');
|
||||||
},
|
},
|
||||||
|
changeTab: (tabName: string) => {
|
||||||
|
this.getters.menuItem(tabName).click();
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
export * from './credentials-modal';
|
export * from './credentials-modal';
|
||||||
export * from './message-box';
|
export * from './message-box';
|
||||||
|
export * from './workflow-sharing-modal';
|
||||||
|
|
26
cypress/pages/modals/workflow-sharing-modal.ts
Normal file
26
cypress/pages/modals/workflow-sharing-modal.ts
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import { BasePage } from '../base';
|
||||||
|
|
||||||
|
export class WorkflowSharingModal extends BasePage {
|
||||||
|
getters = {
|
||||||
|
modal: () => cy.getByTestId('workflowShare-modal', { timeout: 5000 }),
|
||||||
|
usersSelect: () => cy.getByTestId('workflow-sharing-modal-users-select'),
|
||||||
|
saveButton: () => cy.getByTestId('workflow-sharing-modal-save-button'),
|
||||||
|
closeButton: () => this.getters.modal().find('.el-dialog__close').first(),
|
||||||
|
};
|
||||||
|
actions = {
|
||||||
|
addUser: (email: string) => {
|
||||||
|
this.getters.usersSelect().click();
|
||||||
|
this.getters
|
||||||
|
.usersSelect()
|
||||||
|
.get('.el-select-dropdown__item')
|
||||||
|
.contains(email.toLowerCase())
|
||||||
|
.click();
|
||||||
|
},
|
||||||
|
save: () => {
|
||||||
|
this.getters.saveButton().click();
|
||||||
|
},
|
||||||
|
closeModal: () => {
|
||||||
|
this.getters.closeButton().click();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ export class NDV extends BasePage {
|
||||||
container: () => cy.getByTestId('ndv'),
|
container: () => cy.getByTestId('ndv'),
|
||||||
backToCanvas: () => cy.getByTestId('back-to-canvas'),
|
backToCanvas: () => cy.getByTestId('back-to-canvas'),
|
||||||
copyInput: () => cy.getByTestId('copy-input'),
|
copyInput: () => cy.getByTestId('copy-input'),
|
||||||
|
credentialInput: (eq = 0) => cy.getByTestId('node-credentials-select').eq(eq),
|
||||||
nodeExecuteButton: () => cy.getByTestId('node-execute-button'),
|
nodeExecuteButton: () => cy.getByTestId('node-execute-button'),
|
||||||
inputSelect: () => cy.getByTestId('ndv-input-select'),
|
inputSelect: () => cy.getByTestId('ndv-input-select'),
|
||||||
inputOption: () => cy.getByTestId('ndv-input-option'),
|
inputOption: () => cy.getByTestId('ndv-input-option'),
|
||||||
|
@ -24,15 +25,22 @@ export class NDV extends BasePage {
|
||||||
outputTableRows: () => this.getters.outputDataContainer().find('table tr'),
|
outputTableRows: () => this.getters.outputDataContainer().find('table tr'),
|
||||||
outputTableHeaders: () => this.getters.outputDataContainer().find('table thead th'),
|
outputTableHeaders: () => this.getters.outputDataContainer().find('table thead th'),
|
||||||
outputTableRow: (row: number) => this.getters.outputTableRows().eq(row),
|
outputTableRow: (row: number) => this.getters.outputTableRows().eq(row),
|
||||||
outputTbodyCell: (row: number, col: number) => this.getters.outputTableRow(row).find('td').eq(col),
|
outputTbodyCell: (row: number, col: number) =>
|
||||||
|
this.getters.outputTableRow(row).find('td').eq(col),
|
||||||
inputTableRows: () => this.getters.inputDataContainer().find('table tr'),
|
inputTableRows: () => this.getters.inputDataContainer().find('table tr'),
|
||||||
inputTableHeaders: () => this.getters.inputDataContainer().find('table thead th'),
|
inputTableHeaders: () => this.getters.inputDataContainer().find('table thead th'),
|
||||||
inputTableRow: (row: number) => this.getters.inputTableRows().eq(row),
|
inputTableRow: (row: number) => this.getters.inputTableRows().eq(row),
|
||||||
inputTbodyCell: (row: number, col: number) => this.getters.inputTableRow(row).find('td').eq(col),
|
inputTbodyCell: (row: number, col: number) =>
|
||||||
|
this.getters.inputTableRow(row).find('td').eq(col),
|
||||||
inlineExpressionEditorInput: () => cy.getByTestId('inline-expression-editor-input'),
|
inlineExpressionEditorInput: () => cy.getByTestId('inline-expression-editor-input'),
|
||||||
nodeParameters: () => cy.getByTestId('node-parameters'),
|
nodeParameters: () => cy.getByTestId('node-parameters'),
|
||||||
parameterInput: (parameterName: string) => cy.getByTestId(`parameter-input-${parameterName}`),
|
parameterInput: (parameterName: string) => cy.getByTestId(`parameter-input-${parameterName}`),
|
||||||
parameterExpressionPreview: (parameterName: string) => this.getters.nodeParameters().find(`[data-test-id="parameter-input-${parameterName}"] + [data-test-id="parameter-expression-preview"]`),
|
parameterExpressionPreview: (parameterName: string) =>
|
||||||
|
this.getters
|
||||||
|
.nodeParameters()
|
||||||
|
.find(
|
||||||
|
`[data-test-id="parameter-input-${parameterName}"] + [data-test-id="parameter-expression-preview"]`,
|
||||||
|
),
|
||||||
nodeNameContainer: () => cy.getByTestId('node-title-container'),
|
nodeNameContainer: () => cy.getByTestId('node-title-container'),
|
||||||
nodeRenameInput: () => cy.getByTestId('node-rename-input'),
|
nodeRenameInput: () => cy.getByTestId('node-rename-input'),
|
||||||
executePrevious: () => cy.getByTestId('execute-previous-node'),
|
executePrevious: () => cy.getByTestId('execute-previous-node'),
|
||||||
|
@ -77,18 +85,11 @@ export class NDV extends BasePage {
|
||||||
this.getters.parameterInput(parameterName).type(content);
|
this.getters.parameterInput(parameterName).type(content);
|
||||||
},
|
},
|
||||||
selectOptionInParameterDropdown: (parameterName: string, content: string) => {
|
selectOptionInParameterDropdown: (parameterName: string, content: string) => {
|
||||||
this.getters
|
this.getters.parameterInput(parameterName).find('.option-headline').contains(content).click();
|
||||||
.parameterInput(parameterName)
|
|
||||||
.find('.option-headline')
|
|
||||||
.contains(content)
|
|
||||||
.click();
|
|
||||||
},
|
},
|
||||||
rename: (newName: string) => {
|
rename: (newName: string) => {
|
||||||
this.getters.nodeNameContainer().click();
|
this.getters.nodeNameContainer().click();
|
||||||
this.getters.nodeRenameInput()
|
this.getters.nodeRenameInput().should('be.visible').type('{selectall}').type(newName);
|
||||||
.should('be.visible')
|
|
||||||
.type('{selectall}')
|
|
||||||
.type(newName);
|
|
||||||
cy.get('body').type('{enter}');
|
cy.get('body').type('{enter}');
|
||||||
},
|
},
|
||||||
executePrevious: () => {
|
executePrevious: () => {
|
||||||
|
@ -104,10 +105,10 @@ export class NDV extends BasePage {
|
||||||
cy.draganddrop('', droppable);
|
cy.draganddrop('', droppable);
|
||||||
},
|
},
|
||||||
switchInputMode: (type: 'Schema' | 'Table' | 'JSON' | 'Binary') => {
|
switchInputMode: (type: 'Schema' | 'Table' | 'JSON' | 'Binary') => {
|
||||||
this.getters.inputDisplayMode().find('label').contains(type).click({force: true});
|
this.getters.inputDisplayMode().find('label').contains(type).click({ force: true });
|
||||||
},
|
},
|
||||||
switchOutputMode: (type: 'Schema' | 'Table' | 'JSON' | 'Binary') => {
|
switchOutputMode: (type: 'Schema' | 'Table' | 'JSON' | 'Binary') => {
|
||||||
this.getters.outputDisplayMode().find('label').contains(type).click({force: true});
|
this.getters.outputDisplayMode().find('label').contains(type).click({ force: true });
|
||||||
},
|
},
|
||||||
selectInputNode: (nodeName: string) => {
|
selectInputNode: (nodeName: string) => {
|
||||||
this.getters.inputSelect().find('.el-select').click();
|
this.getters.inputSelect().find('.el-select').click();
|
||||||
|
|
|
@ -26,7 +26,7 @@ export class WorkflowPage extends BasePage {
|
||||||
canvasNodeByName: (nodeName: string) =>
|
canvasNodeByName: (nodeName: string) =>
|
||||||
this.getters.canvasNodes().filter(`:contains("${nodeName}")`),
|
this.getters.canvasNodes().filter(`:contains("${nodeName}")`),
|
||||||
getEndpointSelector: (type: 'input' | 'output' | 'plus', nodeName: string, index = 0) => {
|
getEndpointSelector: (type: 'input' | 'output' | 'plus', nodeName: string, index = 0) => {
|
||||||
return `[data-endpoint-name='${nodeName}'][data-endpoint-type='${type}'][data-input-index='${index}']`
|
return `[data-endpoint-name='${nodeName}'][data-endpoint-type='${type}'][data-input-index='${index}']`;
|
||||||
},
|
},
|
||||||
canvasNodeInputEndpointByName: (nodeName: string, index = 0) => {
|
canvasNodeInputEndpointByName: (nodeName: string, index = 0) => {
|
||||||
return cy.get(this.getters.getEndpointSelector('input', nodeName, index));
|
return cy.get(this.getters.getEndpointSelector('input', nodeName, index));
|
||||||
|
@ -79,7 +79,7 @@ export class WorkflowPage extends BasePage {
|
||||||
workflowSettingsSaveButton: () =>
|
workflowSettingsSaveButton: () =>
|
||||||
cy.getByTestId('workflow-settings-save-button').find('button'),
|
cy.getByTestId('workflow-settings-save-button').find('button'),
|
||||||
|
|
||||||
shareButton: () => cy.getByTestId('workflow-share-button').find('button'),
|
shareButton: () => cy.getByTestId('workflow-share-button'),
|
||||||
|
|
||||||
duplicateWorkflowModal: () => cy.getByTestId('duplicate-modal'),
|
duplicateWorkflowModal: () => cy.getByTestId('duplicate-modal'),
|
||||||
nodeViewBackground: () => cy.getByTestId('node-view-background'),
|
nodeViewBackground: () => cy.getByTestId('node-view-background'),
|
||||||
|
@ -155,11 +155,17 @@ export class WorkflowPage extends BasePage {
|
||||||
saveWorkflowOnButtonClick: () => {
|
saveWorkflowOnButtonClick: () => {
|
||||||
this.getters.saveButton().should('contain', 'Save');
|
this.getters.saveButton().should('contain', 'Save');
|
||||||
this.getters.saveButton().click();
|
this.getters.saveButton().click();
|
||||||
this.getters.saveButton().should('contain', 'Saved')
|
this.getters.saveButton().should('contain', 'Saved');
|
||||||
},
|
},
|
||||||
saveWorkflowUsingKeyboardShortcut: () => {
|
saveWorkflowUsingKeyboardShortcut: () => {
|
||||||
cy.get('body').type('{meta}', { release: false }).type('s');
|
cy.get('body').type('{meta}', { release: false }).type('s');
|
||||||
},
|
},
|
||||||
|
setWorkflowName: (name: string) => {
|
||||||
|
this.getters.workflowNameInput().should('be.disabled');
|
||||||
|
this.getters.workflowNameInput().parent().click();
|
||||||
|
this.getters.workflowNameInput().should('be.enabled');
|
||||||
|
this.getters.workflowNameInput().clear().type(name).type('{enter}');
|
||||||
|
},
|
||||||
activateWorkflow: () => {
|
activateWorkflow: () => {
|
||||||
this.getters.activatorSwitch().find('input').first().should('be.enabled');
|
this.getters.activatorSwitch().find('input').first().should('be.enabled');
|
||||||
this.getters.activatorSwitch().click();
|
this.getters.activatorSwitch().click();
|
||||||
|
|
|
@ -40,10 +40,7 @@ Cypress.Commands.add('createFixtureWorkflow', (fixtureKey, workflowName) => {
|
||||||
WorkflowPage.getters
|
WorkflowPage.getters
|
||||||
.workflowImportInput()
|
.workflowImportInput()
|
||||||
.selectFile(`cypress/fixtures/${fixtureKey}`, { force: true });
|
.selectFile(`cypress/fixtures/${fixtureKey}`, { force: true });
|
||||||
WorkflowPage.getters.workflowNameInput().should('be.disabled');
|
WorkflowPage.actions.setWorkflowName(workflowName);
|
||||||
WorkflowPage.getters.workflowNameInput().parent().click();
|
|
||||||
WorkflowPage.getters.workflowNameInput().should('be.enabled');
|
|
||||||
WorkflowPage.getters.workflowNameInput().clear().type(workflowName).type('{enter}');
|
|
||||||
|
|
||||||
WorkflowPage.getters.saveButton().should('contain', 'Saved');
|
WorkflowPage.getters.saveButton().should('contain', 'Saved');
|
||||||
});
|
});
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
:users="usersList"
|
:users="usersList"
|
||||||
:currentUserId="usersStore.currentUser.id"
|
:currentUserId="usersStore.currentUser.id"
|
||||||
:placeholder="$locale.baseText('credentialEdit.credentialSharing.select.placeholder')"
|
:placeholder="$locale.baseText('credentialEdit.credentialSharing.select.placeholder')"
|
||||||
|
data-test-id="credential-sharing-modal-users-select"
|
||||||
@input="onAddSharee"
|
@input="onAddSharee"
|
||||||
>
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
:value="getSelectedName(credentialTypeDescription.name)"
|
:value="getSelectedName(credentialTypeDescription.name)"
|
||||||
disabled
|
disabled
|
||||||
size="small"
|
size="small"
|
||||||
|
data-test-id="node-credentials-select"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
:users="usersList"
|
:users="usersList"
|
||||||
:currentUserId="currentUser.id"
|
:currentUserId="currentUser.id"
|
||||||
:placeholder="$locale.baseText('workflows.shareModal.select.placeholder')"
|
:placeholder="$locale.baseText('workflows.shareModal.select.placeholder')"
|
||||||
|
data-test-id="workflow-sharing-modal-users-select"
|
||||||
@input="onAddSharee"
|
@input="onAddSharee"
|
||||||
>
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
|
@ -108,10 +109,11 @@
|
||||||
</n8n-text>
|
</n8n-text>
|
||||||
<n8n-button
|
<n8n-button
|
||||||
v-show="workflowPermissions.updateSharing"
|
v-show="workflowPermissions.updateSharing"
|
||||||
@click="onSave"
|
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
:disabled="!isDirty"
|
:disabled="!isDirty"
|
||||||
size="medium"
|
size="medium"
|
||||||
|
data-test-id="workflow-sharing-modal-save-button"
|
||||||
|
@click="onSave"
|
||||||
>
|
>
|
||||||
{{ $locale.baseText('workflows.shareModal.save') }}
|
{{ $locale.baseText('workflows.shareModal.save') }}
|
||||||
</n8n-button>
|
</n8n-button>
|
||||||
|
|
Loading…
Reference in a new issue