├── .eslintrc.json
├── .gitignore
├── .npmignore
├── .prettierrc
├── LICENSE
├── README.md
├── azure-pipelines.yml
├── cypress.json
├── cypress
├── fixtures
│ ├── example.json
│ └── prevaluesource.txt
├── integration
│ ├── Content
│ │ ├── content.ts
│ │ ├── routing.ts
│ │ └── urlpicker.ts
│ ├── DataTypes
│ │ └── dataTypes.ts
│ ├── Forms
│ │ ├── dataSourceTest.ts
│ │ ├── formTest.ts
│ │ └── prevaluesourcesTest.ts
│ ├── HelpPanel
│ │ └── systemInformation.ts
│ ├── Login
│ │ └── login.ts
│ ├── Media
│ │ └── media.ts
│ ├── Members
│ │ ├── memberGroups.js
│ │ └── members.js
│ ├── Packages
│ │ └── packages.ts
│ ├── Settings
│ │ ├── dataTypes.ts
│ │ ├── documentTypes.ts
│ │ ├── languages.ts
│ │ ├── macros.ts
│ │ ├── mediaTypes.ts
│ │ ├── memberTypes.ts
│ │ ├── partialsViewMacroFiles.ts
│ │ ├── partialsViews.ts
│ │ ├── relationTypes.ts
│ │ ├── scripts.ts
│ │ ├── stylesheets.ts
│ │ └── templates.ts
│ ├── Tabs
│ │ └── tabs.ts
│ ├── Tour
│ │ └── backofficeTour.ts
│ └── Users
│ │ ├── userGroups.ts
│ │ └── users.ts
├── plugins
│ └── index.js
├── support
│ └── index.js
├── tsconfig.json
└── typings.d.ts
├── jest.config.js
├── package.json
├── postinstall.js
├── src
├── cms
│ ├── builders
│ │ ├── content
│ │ │ ├── contentBuilder.ts
│ │ │ ├── contentVariantBuilder.ts
│ │ │ ├── contentVariantPropertyBuilder.ts
│ │ │ └── index.ts
│ │ ├── dataTypes
│ │ │ ├── approvedColorPickerTypeDataTypeBuilder.ts
│ │ │ ├── checkBoxListDataTypeBuilder.ts
│ │ │ ├── dataTypeBuilder.ts
│ │ │ ├── dropDownDataTypeBuilder.ts
│ │ │ ├── formPickerDataTypeBuilder.ts
│ │ │ ├── gridBuilders
│ │ │ │ ├── gridAreaBuilder.ts
│ │ │ │ ├── gridLayoutBuilder.ts
│ │ │ │ ├── gridRowConfigBuilder.ts
│ │ │ │ ├── gridRteBuilder.ts
│ │ │ │ ├── gridSettingsBuilder.ts
│ │ │ │ ├── gridStylesBuilder.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── rteToolbarOptionsBuilder.ts
│ │ │ │ └── sectionBuilder.ts
│ │ │ ├── gridDataTypeBuilder.ts
│ │ │ ├── index.ts
│ │ │ ├── labelDataTypeBuilder.ts
│ │ │ └── textBoxDataTypeBuilder.ts
│ │ ├── documentTypes
│ │ │ ├── documentTypeBuilder.ts
│ │ │ ├── documentTypeGroupBuilder.ts
│ │ │ ├── documentTypeTabBuilder.ts
│ │ │ ├── index.ts
│ │ │ └── properties
│ │ │ │ ├── approvedColorPickerTypeDataTypeBuilder.ts
│ │ │ │ ├── contentPickerTypePropertyBuilder.ts
│ │ │ │ ├── customDocumentTypePropertyBuilder.ts
│ │ │ │ ├── documentTypePropertyBuilder.ts
│ │ │ │ ├── dropDownDocumentTypePropertyBuilder.ts
│ │ │ │ ├── formPickerDocumentTypePropertyBuilder.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── richTextDocumentTypePropertyBuilder.ts
│ │ │ │ ├── textBoxDocumentTypePropertyBuilder.ts
│ │ │ │ └── urlPickerTypePropertyBuilder.ts
│ │ ├── index.ts
│ │ ├── macroBuilder.ts
│ │ ├── media
│ │ │ ├── index.ts
│ │ │ ├── mediaBuilder.ts
│ │ │ └── mediaPropertyBuilder.ts
│ │ ├── partialViewMacros
│ │ │ └── partialViewMacroBuilder.ts
│ │ ├── partialViews
│ │ │ └── partialViewBuilder.ts
│ │ ├── scriptbuilder.ts
│ │ ├── stylesheetBuilder.ts
│ │ ├── templates
│ │ │ ├── index.ts
│ │ │ └── templateBuilder.ts
│ │ ├── user
│ │ │ ├── index.ts
│ │ │ └── userBuilder.ts
│ │ └── userGroups
│ │ │ ├── index.ts
│ │ │ ├── nodePermissionBuilder.ts
│ │ │ ├── nodePermissionCollectionBuilder.ts
│ │ │ ├── permissionsBuilder.ts
│ │ │ └── userGroupBuilder.ts
│ ├── models
│ │ ├── cmsDocumentType.ts
│ │ ├── dataTypes
│ │ │ ├── approvedColourPickerDataType.ts
│ │ │ ├── checkBoxListDataType.ts
│ │ │ ├── dataType.ts
│ │ │ ├── dataTypePrevalue.ts
│ │ │ ├── dropDownDataType.ts
│ │ │ ├── formPickerDataType.ts
│ │ │ ├── gridDataType.ts
│ │ │ ├── index.ts
│ │ │ ├── labelDataType.ts
│ │ │ └── textBoxDataType.ts
│ │ ├── index.ts
│ │ ├── partialViewMacros
│ │ │ └── partialViewMacro.ts
│ │ ├── properties
│ │ │ ├── baseProperty.ts
│ │ │ ├── dropDownProperty.ts
│ │ │ ├── formPickerProperty.ts
│ │ │ ├── index.ts
│ │ │ └── textBoxProperty.ts
│ │ └── template.ts
│ └── templates
│ │ ├── formPickerTemplate.ts
│ │ ├── index.ts
│ │ └── minimalTemplate.ts
├── cypress
│ └── commands
│ │ ├── chainable.ts
│ │ ├── command.ts
│ │ ├── commandBase.ts
│ │ ├── cycleHackWorkaroundForPureLiveIssue.ts
│ │ ├── dataUmb.ts
│ │ ├── dataUmbScope.ts
│ │ ├── deleteAllContent.ts
│ │ ├── deleteAllDataSources.ts
│ │ ├── deleteAllForms.ts
│ │ ├── deleteAllPreValues.ts
│ │ ├── deleteContentById.ts
│ │ ├── deleteDataSourceByGuid.ts
│ │ ├── deleteDataTypeById.ts
│ │ ├── deleteDataTypesByNamePrefix.ts
│ │ ├── deleteDocumentType.ts
│ │ ├── deleteDocumentTypeById.ts
│ │ ├── deleteDocumentTypesByNamePrefix.ts
│ │ ├── deleteForm.ts
│ │ ├── deleteFormByGuid.ts
│ │ ├── deleteFormsByNamePrefix.ts
│ │ ├── deletePreValueSourceByGuid.ts
│ │ ├── deleteTemplateById.ts
│ │ ├── deleteTemplatesByNamePrefix.ts
│ │ ├── editTemplate.ts
│ │ ├── getAngular.ts
│ │ ├── postFile.ts
│ │ ├── postRequest.ts
│ │ ├── saveCodeFile.ts
│ │ ├── saveContent.ts
│ │ ├── saveDataType.ts
│ │ ├── saveDocumentType.ts
│ │ ├── saveFolder.ts
│ │ ├── saveForm.ts
│ │ ├── saveMacro.ts
│ │ ├── saveMacroWithPartial.ts
│ │ ├── saveMedia.ts
│ │ ├── savePartialView.ts
│ │ ├── savePartialViewMacro.ts
│ │ ├── saveScript.ts
│ │ ├── saveStylesheet.ts
│ │ ├── saveTemplate.ts
│ │ ├── saveUser.ts
│ │ ├── saveUserGroup.ts
│ │ ├── umbracoApiRequest.ts
│ │ ├── umbracoButtonByLabelKey.ts
│ │ ├── umbracoContextMenuAction.ts
│ │ ├── umbracoCreateDocTypeWithContent.ts
│ │ ├── umbracoEditorHeaderName.ts
│ │ ├── umbracoEnsureDataTypeNameNotExists.ts
│ │ ├── umbracoEnsureDocumentTypeNameNotExists.ts
│ │ ├── umbracoEnsureLanguageNameNotExists.ts
│ │ ├── umbracoEnsureMacroNameNotExists.ts
│ │ ├── umbracoEnsureMediaNameNotExists.ts
│ │ ├── umbracoEnsureMediaTypeNameNotExists.ts
│ │ ├── umbracoEnsureMemberEmailNotExists.ts
│ │ ├── umbracoEnsureMemberGroupNameNotExists.ts
│ │ ├── umbracoEnsureMemberTypeNameNotExists.ts
│ │ ├── umbracoEnsureMultipleDocumentTypeNameNotExists.ts
│ │ ├── umbracoEnsurePackageNameNotExists.ts
│ │ ├── umbracoEnsurePartialViewMacroFileNameNotExists.ts
│ │ ├── umbracoEnsurePartialViewNameNotExists.ts
│ │ ├── umbracoEnsureRelationTypeNameNotExists.ts
│ │ ├── umbracoEnsureScriptNameNotExists.ts
│ │ ├── umbracoEnsureStylesheetNameNotExists.ts
│ │ ├── umbracoEnsureTemplateNameNotExists.ts
│ │ ├── umbracoEnsureUserEmailNotExists.ts
│ │ ├── umbracoEnsureUserGroupNameNotExists.ts
│ │ ├── umbracoErrorNotification.ts
│ │ ├── umbracoFileExists.ts
│ │ ├── umbracoGlobalHelp.ts
│ │ ├── umbracoGlobalUser.ts
│ │ ├── umbracoInstall.ts
│ │ ├── umbracoLogin.ts
│ │ ├── umbracoMacroExists.ts
│ │ ├── umbracoPartialViewExists.ts
│ │ ├── umbracoRefreshContentTree.ts
│ │ ├── umbracoScriptExists.ts
│ │ ├── umbracoSection.ts
│ │ ├── umbracoSetCurrentUserLanguage.ts
│ │ ├── umbracoStylesheetExists.ts
│ │ ├── umbracoSuccessNotification.ts
│ │ ├── umbracoTreeItem.ts
│ │ ├── umbracoVerifyRenderedViewContent.ts
│ │ ├── umbracoVerifyScriptContent.ts
│ │ └── umbracoVerifyStylesheetContent.ts
├── forms
│ ├── builders
│ │ ├── fields
│ │ │ ├── conditions
│ │ │ │ ├── formFieldConditionBuilder.ts
│ │ │ │ ├── formFieldConditionRuleBuilder.ts
│ │ │ │ └── index.ts
│ │ │ ├── dropDownFieldBuilder.ts
│ │ │ ├── fileUploadFieldBuilder.ts
│ │ │ ├── formCheckboxFieldBuilder.ts
│ │ │ ├── formDateFieldBuilder.ts
│ │ │ ├── formFieldBuilderBase.ts
│ │ │ ├── formLongAnswerFieldBuilder.ts
│ │ │ ├── formPasswordFieldBuilder.ts
│ │ │ ├── formShortAnswerFieldBuilder.ts
│ │ │ └── index.ts
│ │ ├── formBuilder.ts
│ │ ├── formContainerBuilder.ts
│ │ ├── formFieldSetBuilder.ts
│ │ ├── formPageBuilder.ts
│ │ ├── helpers
│ │ │ ├── contentBuilderHelper.ts
│ │ │ ├── dataSourcesBuilderHelper.ts
│ │ │ ├── dataTypesBuilderHelper.ts
│ │ │ ├── documentTypeBuilderHelper.ts
│ │ │ ├── formBuilderHelper.ts
│ │ │ ├── index.ts
│ │ │ ├── prevalueSourcesBuilderHelper.ts
│ │ │ ├── propertyBuilderHelper.ts
│ │ │ └── templateBuilderHelper.ts
│ │ ├── iBuilder.ts
│ │ ├── index.ts
│ │ └── workflows
│ │ │ ├── formWorkflowBuilder.ts
│ │ │ ├── index.ts
│ │ │ └── workflowTypeSetting.ts
│ ├── models
│ │ ├── checkboxField.ts
│ │ ├── dateField.ts
│ │ ├── dropDownField.ts
│ │ ├── fileUploadField.ts
│ │ ├── formField.ts
│ │ ├── formModel.ts
│ │ ├── index.ts
│ │ ├── longAnswerField.ts
│ │ ├── passwordField.ts
│ │ ├── saveAsUmbracoContentNodeWorkflowModel.ts
│ │ ├── sendEmailRazorModel.ts
│ │ ├── shortAnswerField.ts
│ │ ├── workflow.ts
│ │ └── workflowSettings.ts
│ └── workflows
│ │ ├── changeRecordStateWorkflow.ts
│ │ ├── index.ts
│ │ ├── postAsXMLWorkflow.ts
│ │ ├── saveAsAnXMLFileWorkflow.ts
│ │ ├── saveAsUmbracoContentNodeWorkflow.ts
│ │ ├── sendEmailRazorWorkflow.ts
│ │ ├── sendEmailWorkflow.ts
│ │ ├── sendFormToUrl.ts
│ │ └── sendXsltTransformedEmail.ts
├── helpers
│ ├── aliasHelper.ts
│ ├── jsonHelper.ts
│ └── responseHelper.ts
└── index.ts
├── tests
├── builders
│ ├── contentBuilder.spec.ts
│ ├── dataTypeBuilder.spec.ts
│ ├── documentTypeBuilder.spec.ts
│ └── formBuilder.spec.ts
├── cypress
│ ├── commands
│ │ ├── commandBase.spec.ts
│ │ └── umbracoLogin.spec.ts
│ └── testDoubles
│ │ ├── cyTestDouble.ts
│ │ └── cypressTestDouble.ts
└── tsconfig.json
└── tsconfig.json
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["plugin:@typescript-eslint/recommended"],
3 | "parser": "@typescript-eslint/parser",
4 | "parserOptions": {
5 | "ecmaVersion": 2020, // Allows for the parsing of modern ECMAScript features
6 | "sourceType": "module"
7 | },
8 | "rules": {
9 | "@typescript-eslint/ban-ts-comment" : "warn"
10 | }
11 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # nyc test coverage
18 | .nyc_output
19 |
20 | # Compiled binary addons (http://nodejs.org/api/addons.html)
21 | build/Release
22 |
23 | # Dependency directories
24 | node_modules
25 | jspm_packages
26 |
27 | # Optional npm cache directory
28 | .npm
29 |
30 | # Optional REPL history
31 | .node_repl_history
32 |
33 | # Editors
34 | .idea
35 | .vs
36 |
37 | # Lib
38 | lib
39 |
40 | # npm package lock
41 | package-lock.json
42 | yarn.lock
43 |
44 | others
45 | .DS_Store
46 | /test-results.xml
47 | /cypress/screenshots/
48 | /cypress/videos/
49 | *.tgz
50 | test-results.trx
51 | /coverage
52 | *.trx
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | *.log
2 | npm-debug.log*
3 |
4 | # Editors
5 | .idea
6 | .vs
7 |
8 | # Coverage directory used by tools like istanbul
9 | coverage
10 | .nyc_output
11 |
12 | # Dependency directories
13 | node_modules
14 |
15 | # npm package lock
16 | package-lock.json
17 | yarn.lock
18 |
19 | # project files
20 | src
21 | test
22 | CHANGELOG.md,
23 | test-results.xml
24 | .editorconfig
25 | .eslintignore
26 | .eslintrc
27 | .babelrc
28 | .gitignore
29 |
30 |
31 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 120,
3 | "trailingComma": "all",
4 | "singleQuote": true
5 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2019-present Bjarke Berg
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/azure-pipelines.yml:
--------------------------------------------------------------------------------
1 | # Node.js
2 | # Build a general Node.js project with npm.
3 | # Add steps that analyze code, save build artifacts, deploy, and more:
4 | # https://docs.microsoft.com/azure/devops/pipelines/languages/javascript
5 |
6 | trigger:
7 | - master
8 |
9 | pool:
10 | vmImage: 'ubuntu-latest'
11 |
12 | steps:
13 | - task: NodeTool@0
14 | inputs:
15 | versionSpec: '10.x'
16 | displayName: 'Install Node.js'
17 |
18 | - script: |
19 | npm install
20 | displayName: 'Prepare'
21 |
22 | - task: PublishTestResults@2
23 | displayName: "Publish test results"
24 | inputs:
25 | testResultsFormat: 'VSTest'
26 | testResultsFiles: 'test-results.trx'
27 |
28 | - task: PublishCodeCoverageResults@1
29 | displayName: "Publish code coverage"
30 | inputs:
31 | codeCoverageTool: 'Cobertura'
32 | summaryFileLocation: 'coverage/cobertura-coverage.xml'
33 | reportDirectory: 'coverage'
34 |
35 | - script: |
36 | npm run pack
37 | displayName: 'Prepare and generate package'
38 |
39 | - task: CopyFiles@2
40 | displayName: 'Copy files to artifacts'
41 | inputs:
42 | Contents: |
43 | **/*
44 | !.git/**/*
45 | !node_modules/**/*
46 | TargetFolder: '$(build.artifactstagingdirectory)'
47 |
48 | - task: PublishBuildArtifacts@1
49 | displayName: 'Publish artifacts'
50 | inputs:
51 | PathtoPublish: '$(Build.ArtifactStagingDirectory)'
52 | ArtifactName: 'Content'
53 | publishLocation: 'Container'
54 |
--------------------------------------------------------------------------------
/cypress.json:
--------------------------------------------------------------------------------
1 | {
2 | "baseUrl": "https://localhost:44331",
3 | "viewportHeight": 1024,
4 | "viewportWidth": 1200,
5 | "env": {
6 | "username": "bmb@umbraco.dk",
7 | "password": "1234567890"
8 | },
9 | "ignoreTestFiles": ["**/Forms/*.ts"]
10 | }
11 |
--------------------------------------------------------------------------------
/cypress/fixtures/example.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Using fixtures to represent data",
3 | "email": "hello@cypress.io",
4 | "body": "Fixtures are a great way to mock data for responses to routes"
5 | }
--------------------------------------------------------------------------------
/cypress/fixtures/prevaluesource.txt:
--------------------------------------------------------------------------------
1 | Prevalue1
2 | Prevalue2
3 | Prevalue3
4 | Prevalue4
5 | Prevalue5
--------------------------------------------------------------------------------
/cypress/integration/HelpPanel/systemInformation.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | function openSystemInformation(){
4 | //We have to wait for page to load, if the site is slow
5 | cy.get('[data-element="global-help"]').should('be.visible', {timeout:10000}).click();
6 | cy.get('.umb-help-list-item').last().should('be.visible').click();
7 | cy.get('.umb-drawer-content').scrollTo('bottom', {ensureScrollable : false});
8 | }
9 |
10 | context('System Information', () => {
11 |
12 | beforeEach(() => {
13 | //arrange
14 | cy.umbracoLogin(Cypress.env('username'), Cypress.env('password'));
15 | cy.umbracoSetCurrentUserLanguage('en-US');
16 | });
17 |
18 | it('Check System Info Displays', () => {
19 | openSystemInformation();
20 | cy.get('.table').find('tr').should('have.length', 10);
21 | cy.contains('Current Culture').parent().should('contain', 'en-US');
22 | cy.contains('Current UI Culture').parent().should('contain', 'en-US');
23 | });
24 |
25 | it('Checks language displays correctly after switching', () => {
26 |
27 | //Navigate to edit user and change language
28 | cy.get('[data-element="global-user"]').click();
29 | cy.get('[alias="editUser"]').click();
30 | cy.get('[name="culture"]').select('string:da-DK', {timeout: 10000, force: true});
31 | cy.umbracoButtonByLabelKey('buttons_save').click({force: true});
32 | //Refresh site to display new language
33 | cy.reload();
34 | openSystemInformation();
35 | //Assert
36 | cy.contains('Current Culture').parent().should('contain', 'da-DK');
37 | cy.contains('Current UI Culture').parent().should('contain', 'da-DK');
38 | cy.get('.umb-button__content').last().click();
39 | });
40 | });
41 |
--------------------------------------------------------------------------------
/cypress/integration/Login/login.ts:
--------------------------------------------------------------------------------
1 | ///
2 | context('Login', () => {
3 |
4 | beforeEach(() => {
5 | cy.visit('/umbraco');
6 | });
7 |
8 | it('Login with correct username and password', () => {
9 | const username = Cypress.env('username');
10 | const password = Cypress.env('password');
11 | //Precondition
12 | cy.get('.text-error').should('not.exist');
13 |
14 | //Action
15 | cy.get('#umb-username').type(username);
16 | cy.get('#umb-passwordTwo').type(password);
17 | cy.get('[label-key="general_login"]').click();
18 |
19 | //Assert
20 | cy.url().should('include', '/umbraco#/content')
21 | cy.get('#umb-username').should('not.exist');
22 | cy.get('#umb-passwordTwo').should('not.exist');
23 | });
24 |
25 |
26 | it('Login with correct username but wrong password', () => {
27 | const username = Cypress.env('username');
28 | const password = 'wrong';
29 |
30 | //Precondition
31 | cy.get('.text-error').should('not.exist');
32 |
33 | //Action
34 | cy.get('#umb-username').type(username);
35 | cy.get('#umb-passwordTwo').type(password);
36 | cy.get('[label-key="general_login"]').click();
37 |
38 | //Assert
39 | cy.get('.text-error').should('exist');
40 | cy.get('#umb-username').should('exist');
41 | cy.get('#umb-passwordTwo').should('exist');
42 | });
43 |
44 | it('Login with wrong username and wrong password', () => {
45 | const username = 'wrong-username';
46 | const password = 'wrong';
47 |
48 | //Precondition
49 | cy.get('.text-error').should('not.exist');
50 |
51 | //Action
52 | cy.get('#umb-username').type(username);
53 | cy.get('#umb-passwordTwo').type(password);
54 | cy.get('[label-key="general_login"]').click();
55 |
56 | //Assert
57 | cy.get('.text-error').should('exist');
58 | cy.get('#umb-username').should('exist');
59 | cy.get('#umb-passwordTwo').should('exist');
60 | });
61 |
62 | });
--------------------------------------------------------------------------------
/cypress/integration/Members/memberGroups.js:
--------------------------------------------------------------------------------
1 | context('User Groups', () => {
2 |
3 | beforeEach(() => {
4 | cy.umbracoLogin(Cypress.env('username'), Cypress.env('password'));
5 | });
6 |
7 | it('Create member group', () => {
8 | const name = "Test Group";
9 |
10 | cy.umbracoEnsureMemberGroupNameNotExists(name);
11 |
12 | cy.umbracoSection('member');
13 | cy.get('li .umb-tree-root:contains("Members")').should("be.visible");
14 |
15 | cy.umbracoTreeItem("member", ["Member Groups"]).rightclick();
16 |
17 | cy.umbracoContextMenuAction("action-create").click();
18 |
19 | //Type name
20 | cy.umbracoEditorHeaderName(name);
21 |
22 | // Save
23 | cy.get('.btn-success').click();
24 |
25 | //Assert
26 | cy.umbracoSuccessNotification().should('be.visible');
27 |
28 | //Clean up
29 | cy.umbracoEnsureMemberGroupNameNotExists(name);
30 | });
31 |
32 | });
33 |
--------------------------------------------------------------------------------
/cypress/integration/Members/members.js:
--------------------------------------------------------------------------------
1 | ///
2 | context('Members', () => {
3 |
4 | beforeEach(() => {
5 | cy.umbracoLogin(Cypress.env('username'), Cypress.env('password'));
6 | });
7 |
8 | it('Create member', () => {
9 | const name = "Alice Bobson";
10 | const email = "alice-bobson@acceptancetest.umbraco";
11 | const password = "$AUlkoF*St0kgPiyyVEk5iU5JWdN*F7&";
12 | const passwordTimeout = 20000
13 |
14 | cy.umbracoEnsureMemberEmailNotExists(email);
15 | cy.umbracoSection('member');
16 | cy.get('li .umb-tree-root:contains("Members")').should("be.visible");
17 |
18 | cy.umbracoTreeItem("member", ["Members"]).rightclick();
19 |
20 | cy.umbracoContextMenuAction("action-create").click();
21 | cy.get('.menu-label').first().click();
22 |
23 | //Type name
24 | cy.umbracoEditorHeaderName(name);
25 |
26 | cy.get('input#_umb_login').clear().type(email);
27 | cy.get('input#_umb_email').clear().type(email);
28 | cy.get('input#password').clear().type(password, { timeout: passwordTimeout });
29 | cy.get('input#confirmPassword').clear().type(password, { timeout: passwordTimeout });
30 |
31 | // Save
32 | cy.get('.btn-success').click();
33 |
34 | //Assert
35 | cy.umbracoSuccessNotification().should('be.visible');
36 |
37 | //Clean up
38 | cy.umbracoEnsureMemberEmailNotExists(email);
39 |
40 | });
41 |
42 | });
43 |
--------------------------------------------------------------------------------
/cypress/integration/Settings/dataTypes.ts:
--------------------------------------------------------------------------------
1 | ///
2 | import {LabelDataTypeBuilder} from "../../../src";
3 | context('Data Types', () => {
4 |
5 | beforeEach(() => {
6 | cy.umbracoLogin(Cypress.env('username'), Cypress.env('password'));
7 | });
8 |
9 | it('Create data type', () => {
10 | const name = "Test data type";
11 |
12 | cy.umbracoEnsureDataTypeNameNotExists(name);
13 |
14 | cy.umbracoSection('settings');
15 | cy.get('li .umb-tree-root:contains("Settings")').should("be.visible");
16 |
17 | cy.umbracoTreeItem("settings", ["Data Types"]).rightclick();
18 |
19 | cy.umbracoContextMenuAction("action-create").click();
20 | cy.umbracoContextMenuAction("action-data-type").click();
21 |
22 | //Type name
23 | cy.umbracoEditorHeaderName(name);
24 |
25 |
26 | cy.get('select[name="selectedEditor"]').select('Label');
27 |
28 | cy.get('.umb-property-editor select').select('Time');
29 |
30 | //Save
31 | cy.get('.btn-success').click();
32 |
33 | //Assert
34 | cy.umbracoSuccessNotification().should('be.visible');
35 |
36 | //Clean up
37 | cy.umbracoEnsureDataTypeNameNotExists(name);
38 | });
39 |
40 | it('Delete data type', () => {
41 | const name = "Test data type";
42 | cy.umbracoEnsureDataTypeNameNotExists(name);
43 |
44 | const dataType = new LabelDataTypeBuilder()
45 | .withSaveNewAction()
46 | .withName(name)
47 | .build();
48 |
49 | cy.saveDataType(dataType);
50 |
51 | cy.umbracoSection('settings');
52 | cy.get('li .umb-tree-root:contains("Settings")').should("be.visible");
53 |
54 | cy.umbracoTreeItem("settings", ["Data Types", name]).rightclick();
55 |
56 | cy.umbracoContextMenuAction("action-delete").click();
57 |
58 | cy.umbracoButtonByLabelKey("general_delete").click();
59 |
60 | cy.contains(name).should('not.exist');
61 |
62 | cy.umbracoEnsureDataTypeNameNotExists(name);
63 |
64 |
65 | });
66 | });
67 |
--------------------------------------------------------------------------------
/cypress/integration/Settings/languages.ts:
--------------------------------------------------------------------------------
1 | ///
2 | context('Languages', () => {
3 |
4 | beforeEach(() => {
5 | cy.umbracoLogin(Cypress.env('username'), Cypress.env('password'));
6 | });
7 |
8 | it('Add language', () => {
9 | const name = "Kyrgyz (Kyrgyzstan)"; // Must be an option in the select box
10 |
11 | cy.umbracoEnsureLanguageNameNotExists(name);
12 |
13 | cy.umbracoSection('settings');
14 | cy.get('li .umb-tree-root:contains("Settings")').should("be.visible");
15 |
16 | cy.umbracoTreeItem("settings", ["Languages"]).click();
17 |
18 | cy.umbracoButtonByLabelKey("languages_addLanguage").click();
19 |
20 | cy.get('select[name="newLang"]').select(name);
21 |
22 | // //Save
23 | cy.get('.btn-success').click();
24 |
25 | //Assert
26 | cy.umbracoSuccessNotification().should('be.visible');
27 |
28 | //Clean up
29 | cy.umbracoEnsureLanguageNameNotExists(name);
30 | });
31 |
32 | });
33 |
--------------------------------------------------------------------------------
/cypress/integration/Settings/macros.ts:
--------------------------------------------------------------------------------
1 | ///
2 | import { PartialViewMacroBuilder, MacroBuilder, DocumentTypeBuilder, ContentBuilder, AliasHelper, GridDataTypeBuilder } from '../../../src';
3 |
4 | context('Macros', () => {
5 |
6 | beforeEach(() => {
7 | cy.umbracoLogin(Cypress.env('username'), Cypress.env('password'));
8 | });
9 |
10 | function refreshContentTree(){
11 | // Refresh to update the tree
12 | cy.get('li .umb-tree-root:contains("Content")').should("be.visible").rightclick();
13 | cy.umbracoContextMenuAction("action-refreshNode").click();
14 | // We have to wait in case the execution is slow, otherwise we'll try and click the item before it appears in the UI
15 | cy.get('.umb-tree-item__inner').should('exist', {timeout: 10000});
16 | }
17 |
18 | it('Create macro', () => {
19 | const name = "Test macro";
20 |
21 | cy.umbracoEnsureMacroNameNotExists(name);
22 |
23 | cy.umbracoSection('settings');
24 | cy.get('li .umb-tree-root:contains("Settings")').should("be.visible");
25 |
26 | cy.umbracoTreeItem("settings", ["Macros"]).rightclick();
27 |
28 | cy.umbracoContextMenuAction("action-create").click();
29 |
30 | cy.get('form[name="createMacroForm"]').within(($form) => {
31 | cy.get('input[name="itemKey"]').type(name);
32 | cy.get(".btn-primary").click();
33 | });
34 |
35 | cy.location().should((loc) => {
36 | expect(loc.hash).to.include('#/settings/macros/edit/')
37 | });
38 |
39 | //Clean up
40 | cy.umbracoEnsureMacroNameNotExists(name);
41 | });
42 | });
43 |
--------------------------------------------------------------------------------
/cypress/integration/Settings/mediaTypes.ts:
--------------------------------------------------------------------------------
1 | ///
2 | context('Media Types', () => {
3 |
4 | beforeEach(() => {
5 | cy.umbracoLogin(Cypress.env('username'), Cypress.env('password'));
6 | });
7 |
8 | it('Create media type', () => {
9 | const name = "Test media type";
10 |
11 | cy.umbracoEnsureMediaTypeNameNotExists(name);
12 |
13 | cy.umbracoSection('settings');
14 | cy.get('li .umb-tree-root:contains("Settings")').should("be.visible");
15 |
16 | cy.umbracoTreeItem("settings", ["Media Types"]).rightclick();
17 |
18 | cy.umbracoContextMenuAction("action-create").click();
19 | cy.get('.menu-label').first().click(); // TODO: Fucked we cant use something like cy.umbracoContextMenuAction("action-mediaType").click();
20 |
21 |
22 | //Type name
23 | cy.umbracoEditorHeaderName(name);
24 |
25 |
26 | cy.get('[data-element="group-add"]').click();
27 |
28 | cy.get('.umb-group-builder__group-title-input').type('Group name');
29 | cy.get('[data-element="property-add"]').click();
30 | cy.get('.editor-label').type('property name');
31 | cy.get('[data-element="editor-add"]').click();
32 |
33 | //Search for textstring
34 | cy.get('#datatype-search').type('Textstring');
35 |
36 | // Choose first item
37 | cy.get('ul.umb-card-grid li [title="Textstring"]').closest("li").click();
38 |
39 | // Save property
40 | cy.get('.btn-success').last().click();
41 |
42 | //Save
43 | cy.get('.btn-success').click();
44 |
45 | //Assert
46 | cy.umbracoSuccessNotification().should('be.visible');
47 |
48 | //Clean up
49 | cy.umbracoEnsureMediaTypeNameNotExists(name);
50 | });
51 |
52 | });
53 |
--------------------------------------------------------------------------------
/cypress/integration/Settings/memberTypes.ts:
--------------------------------------------------------------------------------
1 | ///
2 | context('Member Types', () => {
3 |
4 | beforeEach(() => {
5 | cy.umbracoLogin(Cypress.env('username'), Cypress.env('password'));
6 | });
7 |
8 | it('Create member type', () => {
9 | const name = "Test member type";
10 |
11 | cy.umbracoEnsureMemberTypeNameNotExists(name);
12 |
13 | cy.umbracoSection('settings');
14 | cy.get('li .umb-tree-root:contains("Settings")').should("be.visible");
15 |
16 | cy.umbracoTreeItem("settings", ["Member Types"]).rightclick();
17 |
18 | cy.umbracoContextMenuAction("action-create").click();
19 |
20 | //Type name
21 | cy.umbracoEditorHeaderName(name);
22 |
23 |
24 | cy.get('[data-element="group-add"]').click();
25 |
26 | cy.get('.umb-group-builder__group-title-input').type('Group name');
27 | cy.get('[data-element="property-add"]').click();
28 | cy.get('.editor-label').type('property name');
29 | cy.get('[data-element="editor-add"]').click();
30 |
31 | //Search for textstring
32 | cy.get('#datatype-search').type('Textstring');
33 |
34 | // Choose first item
35 | cy.get('ul.umb-card-grid li [title="Textstring"]').closest("li").click();
36 |
37 | // Save property
38 | cy.get('.btn-success').last().click();
39 |
40 | //Save
41 | cy.get('.btn-success').click();
42 |
43 | //Assert
44 | cy.umbracoSuccessNotification().should('be.visible');
45 |
46 | //Clean up
47 | cy.umbracoEnsureMemberTypeNameNotExists(name);
48 | });
49 |
50 | });
51 |
--------------------------------------------------------------------------------
/cypress/integration/Settings/relationTypes.ts:
--------------------------------------------------------------------------------
1 | ///
2 | context('Relation Types', () => {
3 |
4 | beforeEach(() => {
5 | cy.umbracoLogin(Cypress.env('username'), Cypress.env('password'));
6 | });
7 |
8 | it('Create relation type', () => {
9 | const name = "Test relation type";
10 |
11 | cy.umbracoEnsureRelationTypeNameNotExists(name);
12 |
13 | cy.umbracoSection('settings');
14 | cy.get('li .umb-tree-root:contains("Settings")').should("be.visible");
15 |
16 | cy.umbracoTreeItem("settings", ["Relation Types"]).rightclick();
17 |
18 | cy.umbracoContextMenuAction("action-create").click();
19 |
20 | cy.get('form[name="createRelationTypeForm"]').within(($form) => {
21 | cy.get('input[name="relationTypeName"]').type(name);
22 |
23 | cy.get('[name="relationType-direction"] input').first().click({force:true});
24 |
25 | cy.get('select[name="relationType-parent"]').select('Document');
26 |
27 | cy.get('select[name="relationType-child"]').select('Media');
28 |
29 | cy.get(".btn-primary").click();
30 | });
31 |
32 | cy.location().should((loc) => {
33 | expect(loc.hash).to.include('#/settings/relationTypes/edit/')
34 | })
35 |
36 | //Clean up
37 | cy.umbracoEnsureRelationTypeNameNotExists(name);
38 | });
39 |
40 | });
41 |
--------------------------------------------------------------------------------
/cypress/integration/Users/users.ts:
--------------------------------------------------------------------------------
1 | ///
2 | context('Users', () => {
3 |
4 | beforeEach(() => {
5 | cy.umbracoLogin(Cypress.env('username'), Cypress.env('password'));
6 | });
7 |
8 | it('Create user', () => {
9 | const name = "Alice Bobson";
10 | const email = "alice-bobson@acceptancetest.umbraco";
11 |
12 | cy.umbracoEnsureUserEmailNotExists(email);
13 | cy.umbracoSection('users');
14 | cy.umbracoButtonByLabelKey("user_createUser").click();
15 |
16 |
17 | cy.get('input[name="name"]').type(name);
18 | cy.get('input[name="email"]').type(email);
19 |
20 | cy.get('.umb-node-preview-add').click();
21 | cy.get('.umb-user-group-picker-list-item:nth-child(1) > .umb-user-group-picker__action').click();
22 | cy.get('.umb-user-group-picker-list-item:nth-child(2) > .umb-user-group-picker__action').click();
23 | cy.get('.btn-success').click();
24 |
25 | cy.get('.umb-button > .btn > .umb-button__content').click();
26 |
27 |
28 | cy.umbracoButtonByLabelKey("user_goToProfile").should('be.visible');
29 |
30 | //Clean up
31 | cy.umbracoEnsureUserEmailNotExists(email);
32 |
33 | });
34 |
35 | });
36 |
--------------------------------------------------------------------------------
/cypress/plugins/index.js:
--------------------------------------------------------------------------------
1 | module.exports = (on, config) => {
2 | on('before:browser:launch', (browser, launchOptions) => {
3 | if (browser.name === 'chrome' && browser.isHeadless) {
4 | launchOptions.args.push('--window-size=1400,1200')
5 |
6 | return launchOptions
7 | }
8 | });
9 | on('task', {
10 | isFileExist
11 | });
12 | }
13 |
14 |
15 | const { isFileExist } = require('cy-verify-downloads');
16 |
17 | module.exports = (on, config) => {
18 | on('task', { isFileExist })
19 | }
--------------------------------------------------------------------------------
/cypress/support/index.js:
--------------------------------------------------------------------------------
1 | // ***********************************************************
2 | // This example support/index.js is processed and
3 | // loaded automatically before your test files.
4 | //
5 | // This is a great place to put global configuration and
6 | // behavior that modifies Cypress.
7 | //
8 | // You can change the location of this file or turn off
9 | // automatically serving support files with the
10 | // 'supportFile' configuration option.
11 | //
12 | // You can read more here:
13 | // https://on.cypress.io/configuration
14 | // ***********************************************************
15 |
16 | // Import commands.js using ES2015 syntax:
17 | import {Command} from '../../src/cypress/commands/command';
18 | import {Chainable} from '../../src/cypress/commands/chainable';
19 | require('cy-verify-downloads').addCustomCommand();
20 |
21 | new Chainable();
22 | new Command().registerCypressCommands();
23 | import 'cypress-file-upload';
--------------------------------------------------------------------------------
/cypress/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "types":[
4 | "cypress"
5 | ],
6 | "include": [
7 | "**/*.ts",
8 | "../src/cypress/commands/**/*.ts"
9 | ]
10 |
11 | }
--------------------------------------------------------------------------------
/cypress/typings.d.ts:
--------------------------------------------------------------------------------
1 | // type definitions for Cypress object "cy"
2 | ///
3 |
4 | // type definitions for custom commands like "createDefaultTodos"
5 | //
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: 'ts-jest',
3 | testEnvironment: 'node',
4 | "reporters": ["default",
5 | [
6 | "jest-trx-results-processor",
7 | {
8 | "outputFile": "test-results.trx"
9 | }
10 | ]
11 | ]
12 | };
--------------------------------------------------------------------------------
/postinstall.js:
--------------------------------------------------------------------------------
1 | const ncp=require('ncp').ncp;
2 | const fs = require('fs');
3 | const path= require('path');
4 |
5 | const basepath = __dirname;
6 | const src = path.join(basepath,'src','cypress','commands','chainable.ts');
7 | const dst = path.join(basepath,'..','..','cypress','support', 'chainable.ts');
8 |
9 | const fixturesSrc=path.join(basepath,'node_modules','umbraco-cypress-testhelpers','cypress','fixtures','prevaluesource.txt');
10 | const fixturesDst = path.join(basepath,'cypress','fixtures', 'prevaluesouce.txt');
11 |
12 | try {
13 | if (fs.existsSync(src)) {
14 | console.log('Copy chainable.ts file');
15 |
16 | ncp(src, dst);
17 | }
18 | } catch(err) {
19 | console.error(err)
20 | }
21 | try {
22 | if (fs.existsSync(fixturesSrc)) {
23 | console.log('Copy prevaluesource.txt file');
24 | ncp(fixturesSrc, fixturesDst);
25 | }
26 | } catch(err) {
27 | console.error(fixturesDst)
28 | }
--------------------------------------------------------------------------------
/src/cms/builders/content/contentBuilder.ts:
--------------------------------------------------------------------------------
1 | import { ContentVariantBuilder } from './contentVariantBuilder';
2 |
3 | export class ContentBuilder {
4 | id;
5 | contentTypeAlias;
6 | parentId;
7 | action;
8 | expireDate;
9 | releaseDate;
10 | templateAlias;
11 |
12 | contentVariantBuilders;
13 |
14 | constructor() {
15 | this.contentVariantBuilders = [];
16 | }
17 |
18 | withContentTypeAlias(contentTypeAlias) {
19 | this.contentTypeAlias = contentTypeAlias;
20 | return this;
21 | }
22 |
23 | withTemplateAlias(templateAlias) {
24 | this.templateAlias = templateAlias;
25 | return this;
26 | }
27 |
28 | withAction(action) {
29 | this.action = action;
30 | return this;
31 | }
32 |
33 | withParent(parentId) {
34 | this.parentId = parentId;
35 | return this;
36 | }
37 |
38 | addVariant() {
39 | const builder = new ContentVariantBuilder(this);
40 |
41 | this.contentVariantBuilders.push(builder);
42 |
43 | return builder;
44 | }
45 |
46 | build() {
47 | return {
48 | id: this.id || 0,
49 | contentTypeAlias: this.contentTypeAlias || null,
50 | parentId: this.parentId || -1,
51 | action: this.action || 'publishNew',
52 | variants: this.contentVariantBuilders.map((builder) => {
53 | return builder.build();
54 | }),
55 | expireDate: this.expireDate || null,
56 | releaseDate: this.releaseDate || null,
57 | templateAlias: this.templateAlias || null,
58 | };
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/cms/builders/content/contentVariantBuilder.ts:
--------------------------------------------------------------------------------
1 | import faker from 'faker';
2 | import { ContentVariantPropertyBuilder } from './contentVariantPropertyBuilder';
3 |
4 | export class ContentVariantBuilder {
5 | parentBuilder;
6 | id;
7 | name;
8 | culture;
9 | publish;
10 | save;
11 | releaseDate;
12 | expireDate;
13 |
14 | contentVariantPropertyBuilders;
15 |
16 | constructor(parentBuilder) {
17 | this.parentBuilder = parentBuilder;
18 | this.contentVariantPropertyBuilders = [];
19 | }
20 |
21 | addProperty() {
22 | const builder = new ContentVariantPropertyBuilder(this);
23 |
24 | this.contentVariantPropertyBuilders.push(builder);
25 |
26 | return builder;
27 | }
28 | withCulture(culture) {
29 | this.culture = culture;
30 | return this;
31 | }
32 | withPublish(publish) {
33 | this.publish = publish;
34 | return this;
35 | }
36 | withSave(save) {
37 | this.save = save;
38 | return this;
39 | }
40 | withName(name) {
41 | this.name = name;
42 | return this;
43 | }
44 | done() {
45 | return this.parentBuilder;
46 | }
47 |
48 | build() {
49 | const name = this.name || faker.random.uuid();
50 |
51 | return {
52 | name,
53 | id: this.id || 0,
54 | properties: this.contentVariantPropertyBuilders.map((builder) => {
55 | return builder.build();
56 | }),
57 | culture: this.culture || null,
58 | publish: this.publish || false,
59 | save: this.save || false,
60 | releaseDate: this.releaseDate || null,
61 | expireDate: this.expireDate || null,
62 | };
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/cms/builders/content/contentVariantPropertyBuilder.ts:
--------------------------------------------------------------------------------
1 | export class ContentVariantPropertyBuilder {
2 | parentBuilder;
3 |
4 | id;
5 | alias;
6 | value;
7 |
8 | constructor(parentBuilder) {
9 | this.parentBuilder = parentBuilder;
10 | }
11 |
12 | withAlias(alias) {
13 | this.alias = alias;
14 | return this;
15 | }
16 |
17 | withValue(value) {
18 | this.value = value;
19 | return this;
20 | }
21 |
22 | done() {
23 | return this.parentBuilder;
24 | }
25 |
26 | build() {
27 | return {
28 | id: this.id || 0,
29 | alias: this.alias || null,
30 | value: this.value || null,
31 | };
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/cms/builders/content/index.ts:
--------------------------------------------------------------------------------
1 | export { ContentBuilder } from './contentBuilder';
2 | export { ContentVariantBuilder } from './contentVariantBuilder';
3 | export { ContentVariantPropertyBuilder } from './contentVariantPropertyBuilder';
4 |
--------------------------------------------------------------------------------
/src/cms/builders/dataTypes/approvedColorPickerTypeDataTypeBuilder.ts:
--------------------------------------------------------------------------------
1 | import { ApprovedColourPickerDataType } from '../../models/dataTypes/approvedColourPickerDataType';
2 | import { DataTypeBuilder } from './dataTypeBuilder';
3 |
4 | export class ApprovedColorPickerDataTypeBuilder extends DataTypeBuilder {
5 | constructor(
6 | private approvedColourPickerDataTypeBuilder: ApprovedColourPickerDataType = new ApprovedColourPickerDataType(),
7 | ) {
8 | super(approvedColourPickerDataTypeBuilder);
9 | }
10 | withPrevalues(value: string[], multiSelect = false) {
11 | this.approvedColourPickerDataTypeBuilder.addPrevalues(value, multiSelect);
12 | return this;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/cms/builders/dataTypes/checkBoxListDataTypeBuilder.ts:
--------------------------------------------------------------------------------
1 | import { DataTypeBuilder } from './dataTypeBuilder';
2 | import { CheckBoxListDataType } from '../../models/dataTypes/checkBoxListDataType';
3 |
4 | export class CheckBoxListDataTypeBuilder extends DataTypeBuilder {
5 | constructor(private checkBoxListDataType: CheckBoxListDataType = new CheckBoxListDataType()) {
6 | super(checkBoxListDataType);
7 | }
8 | withPrevalues(value: string[], multiSelect = false) {
9 | this.checkBoxListDataType.addPrevalues(value, multiSelect);
10 | return this;
11 | }
12 | }
--------------------------------------------------------------------------------
/src/cms/builders/dataTypes/dataTypeBuilder.ts:
--------------------------------------------------------------------------------
1 | import { DataType } from '../../models/dataTypes/dataType';
2 |
3 | export class DataTypeBuilder {
4 | constructor(public dataType: DataType) {}
5 | public withSaveAction() {
6 | this.dataType.action = 'save';
7 | return this;
8 | }
9 | public withSaveNewAction() {
10 | this.dataType.action = 'saveNew';
11 | return this;
12 | }
13 | public withId(id) {
14 | this.dataType.id = id;
15 | return this;
16 | }
17 | public withName(name) {
18 | this.dataType.name = name;
19 | return this;
20 | }
21 |
22 | public build(): DataType {
23 | return this.dataType;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/cms/builders/dataTypes/dropDownDataTypeBuilder.ts:
--------------------------------------------------------------------------------
1 | import { DataTypeBuilder } from './dataTypeBuilder';
2 | import { DropDownDataType } from '../../models/dataTypes/dropDownDataType';
3 |
4 | export class DropDownDataTypeBuilder extends DataTypeBuilder {
5 | constructor(private dropDownDataType: DropDownDataType = new DropDownDataType()) {
6 | super(dropDownDataType);
7 | }
8 | withPrevalues(value: string[], multiSelect = false) {
9 | this.dropDownDataType.addPrevalues(value, multiSelect);
10 | return this;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/cms/builders/dataTypes/formPickerDataTypeBuilder.ts:
--------------------------------------------------------------------------------
1 | import { DataTypeBuilder } from './dataTypeBuilder';
2 | import { FormPickerDataType } from '../../models/dataTypes/formPickerDataType';
3 |
4 | export class FormPickerDataTypeBuilder extends DataTypeBuilder {
5 | constructor(private formPickerDataType: FormPickerDataType = new FormPickerDataType()) {
6 | super(formPickerDataType);
7 | }
8 |
9 | withAllowedForms(formIds: string[]) {
10 | this.formPickerDataType.addPrevalues(formIds);
11 | return this;
12 | }
13 | withAllowedForm(formId: string) {
14 | return this.withAllowedForms([formId]);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/cms/builders/dataTypes/gridBuilders/gridAreaBuilder.ts:
--------------------------------------------------------------------------------
1 | import { GridRowConfigBuilder } from './gridRowConfigBuilder';
2 |
3 | export class GridAreaBuilder {
4 | parentBuilder;
5 | gridSize;
6 | editors;
7 | allowed;
8 | maxItems;
9 |
10 | constructor(parentBuilder: GridRowConfigBuilder) {
11 | this.parentBuilder = parentBuilder;
12 | this.editors = [];
13 | this.allowed = [];
14 | }
15 |
16 | withGridSize(gridSize: number) {
17 | this.gridSize = gridSize;
18 | return this;
19 | }
20 |
21 | withMaxItems(maxItems: number) {
22 | this.maxItems = maxItems;
23 | return this;
24 | }
25 |
26 | withEditor(editor) {
27 | this.editors.push(editor);
28 | return this;
29 | }
30 |
31 | withAllowRTE() {
32 | this.allowed.push('rte');
33 | return this;
34 | }
35 |
36 | withAllowImage() {
37 | this.allowed.push('media');
38 | return this;
39 | }
40 |
41 | withAllowMacro() {
42 | this.allowed.push('macro');
43 | return this;
44 | }
45 |
46 | withAllowEmbed() {
47 | this.allowed.push('embed');
48 | return this;
49 | }
50 |
51 | withAllowHeadline() {
52 | this.allowed.push('headline');
53 | return this;
54 | }
55 |
56 | withAllowQuote() {
57 | this.allowed.push('quote');
58 | return this;
59 | }
60 |
61 | withAllowAll() {
62 | this.allowed = [];
63 | return this;
64 | }
65 |
66 | done(): GridRowConfigBuilder {
67 | return this.parentBuilder;
68 | }
69 |
70 | build() {
71 | const area = { grid: this.gridSize };
72 |
73 | if (this.editors.length > 0) {
74 | Object.assign(area, { editors: this.editors });
75 | }
76 |
77 | if (this.allowed.length > 0) {
78 | Object.assign(area, {
79 | allowAll: false,
80 | allowed: this.allowed,
81 | });
82 | }
83 |
84 | if (this.maxItems) {
85 | Object.assign(area, { maxItems: this.maxItems });
86 | }
87 |
88 | return area;
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/cms/builders/dataTypes/gridBuilders/gridLayoutBuilder.ts:
--------------------------------------------------------------------------------
1 | import { GridDataTypeBuilder } from './../gridDataTypeBuilder';
2 | import { SectionBuilder } from './sectionBuilder';
3 |
4 | export class GridLayoutBuilder {
5 | parentBuilder: GridDataTypeBuilder;
6 | name;
7 | sectionBuilders;
8 |
9 | constructor(parrentBuilder: GridDataTypeBuilder) {
10 | this.parentBuilder = parrentBuilder;
11 | this.sectionBuilders = [];
12 | }
13 |
14 | withName(name) {
15 | this.name = name;
16 | return this;
17 | }
18 |
19 | addSection(sectionBuilder?: SectionBuilder) {
20 | const builder = sectionBuilder === null || sectionBuilder === undefined ? new SectionBuilder(this) : sectionBuilder;
21 | this.sectionBuilders.push(builder);
22 | return builder;
23 | }
24 |
25 | withSimpleSection(gridSize: number) {
26 | this.addSection().withGridSize(gridSize).done();
27 | return this;
28 | }
29 |
30 | done(): GridDataTypeBuilder {
31 | return this.parentBuilder;
32 | }
33 |
34 | build() {
35 | return {
36 | name: this.name,
37 | sections: this.sectionBuilders.map((builder) => {
38 | return builder.build();
39 | }),
40 | };
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/cms/builders/dataTypes/gridBuilders/gridRowConfigBuilder.ts:
--------------------------------------------------------------------------------
1 | import { GridDataTypeBuilder } from '../gridDataTypeBuilder';
2 | import { GridAreaBuilder } from './gridAreaBuilder';
3 |
4 | export class GridRowConfigBuilder {
5 | parentBuilder;
6 | label;
7 | name;
8 | areas;
9 | allowed;
10 |
11 | constructor(parentBuilder: GridDataTypeBuilder) {
12 | this.parentBuilder = parentBuilder;
13 | this.areas = [];
14 | }
15 |
16 | withName(name) {
17 | this.name = name;
18 | return this;
19 | }
20 |
21 | withLabel(label) {
22 | this.label = label;
23 | return this;
24 | }
25 |
26 | withAllowed(allowed: boolean) {
27 | this.allowed = allowed;
28 | return this;
29 | }
30 |
31 | addArea(areaBuilder?: GridAreaBuilder) {
32 | const builder = areaBuilder === null || areaBuilder === undefined ? new GridAreaBuilder(this) : areaBuilder;
33 |
34 | this.areas.push(builder);
35 | return builder;
36 | }
37 |
38 | withSimpleArea(gridSize: number) {
39 | this.addArea().withGridSize(gridSize).done();
40 | return this;
41 | }
42 |
43 | done(): GridDataTypeBuilder {
44 | return this.parentBuilder;
45 | }
46 |
47 | build() {
48 | if (this.allowed) {
49 | return {
50 | allowed: this.allowed,
51 | name: this.name,
52 | label: this.label || this.name,
53 | areas: this.areas.map((builder) => {
54 | return builder.build();
55 | }),
56 | };
57 | }
58 | return {
59 | name: this.name,
60 | label: this.label || this.name,
61 | areas: this.areas.map((builder) => {
62 | return builder.build();
63 | }),
64 | };
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/cms/builders/dataTypes/gridBuilders/gridRteBuilder.ts:
--------------------------------------------------------------------------------
1 | import { GridDataTypeBuilder } from '../gridDataTypeBuilder';
2 | import { RteToolbarOptionsBuilder } from './rteToolbarOptionsBuilder';
3 |
4 | export class GridRteBuilder {
5 | parentBuilder;
6 | maxImageSize;
7 | mode;
8 | stylesheets;
9 | toolbarOptionsBuilder;
10 | dimensions;
11 |
12 | constructor(parentBuilder: GridDataTypeBuilder) {
13 | this.parentBuilder = parentBuilder;
14 | this.stylesheets = [];
15 | }
16 |
17 | withClassicMode() {
18 | this.mode = 'classic';
19 | return this;
20 | }
21 |
22 | withDistractionFreeMode() {
23 | this.mode = 'distraction-free';
24 | return this;
25 | }
26 |
27 | withMaxImageSize(imageSize: number) {
28 | this.maxImageSize = imageSize;
29 | return this;
30 | }
31 |
32 | withDimensions(width: number, height: number) {
33 | this.dimensions = {
34 | width: width,
35 | height: height,
36 | };
37 | return this;
38 | }
39 |
40 | withStylesheet(virtualPath: string) {
41 | this.stylesheets.push(virtualPath);
42 | return this;
43 | }
44 |
45 | addToolBarOptions(optionsBuilder?: RteToolbarOptionsBuilder) {
46 | const builder =
47 | optionsBuilder === null || optionsBuilder === undefined ? new RteToolbarOptionsBuilder(this) : optionsBuilder;
48 |
49 | this.toolbarOptionsBuilder = builder;
50 | return builder;
51 | }
52 |
53 | done() {
54 | return this.parentBuilder;
55 | }
56 |
57 | build() {
58 | const RTE = {
59 | maxImageSize: this.maxImageSize || 500,
60 | mode: this.mode || 'classic',
61 | stylesheets: this.stylesheets,
62 | toolbar: this.toolbarOptionsBuilder.build(),
63 | };
64 |
65 | if (this.dimensions) {
66 | Object.assign(RTE, { dimensions: this.dimensions });
67 | }
68 |
69 | return RTE;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/cms/builders/dataTypes/gridBuilders/gridSettingsBuilder.ts:
--------------------------------------------------------------------------------
1 | import { GridDataTypeBuilder } from '../gridDataTypeBuilder';
2 |
3 | export class GridSettingsbuilder {
4 | parentBuilder;
5 | description;
6 | key;
7 | label;
8 | view;
9 |
10 | constructor(parentbuilder: GridDataTypeBuilder) {
11 | this.parentBuilder = parentbuilder;
12 | }
13 |
14 | withDescription(description: string) {
15 | this.description = description;
16 | return this;
17 | }
18 |
19 | withKey(key: string) {
20 | this.key = key;
21 | return this;
22 | }
23 |
24 | withLabel(label: string) {
25 | this.label = label;
26 | return this;
27 | }
28 |
29 | withView(view: string) {
30 | this.view = view;
31 | return this;
32 | }
33 |
34 | done(): GridDataTypeBuilder {
35 | return this.parentBuilder;
36 | }
37 |
38 | build() {
39 | return {
40 | description: this.description,
41 | key: this.key,
42 | label: this.label,
43 | view: this.view,
44 | };
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/cms/builders/dataTypes/gridBuilders/gridStylesBuilder.ts:
--------------------------------------------------------------------------------
1 | import { GridDataTypeBuilder } from '../gridDataTypeBuilder';
2 | import { GridSettingsbuilder } from './gridSettingsBuilder';
3 |
4 | export class GridStylesBuilder extends GridSettingsbuilder {
5 | modifier;
6 |
7 | constructor(parentbuilder: GridDataTypeBuilder) {
8 | super(parentbuilder);
9 | }
10 |
11 | withModifier(modifier: string) {
12 | this.modifier = modifier;
13 | return this;
14 | }
15 |
16 | build() {
17 | return {
18 | description: this.description,
19 | key: this.key,
20 | label: this.label,
21 | view: this.view,
22 | modifier: this.modifier,
23 | };
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/cms/builders/dataTypes/gridBuilders/index.ts:
--------------------------------------------------------------------------------
1 | export { GridLayoutBuilder } from './gridLayoutBuilder';
2 | export { SectionBuilder } from './sectionBuilder';
3 | export { GridRowConfigBuilder } from './gridRowConfigBuilder';
4 | export { GridAreaBuilder } from './gridAreaBuilder';
5 | export { GridRteBuilder } from './gridRteBuilder';
6 | export { RteToolbarOptionsBuilder } from './rteToolbarOptionsBuilder';
7 | export { GridSettingsbuilder } from './gridSettingsBuilder';
8 | export { GridStylesBuilder } from './gridStylesBuilder';
9 |
--------------------------------------------------------------------------------
/src/cms/builders/dataTypes/gridBuilders/sectionBuilder.ts:
--------------------------------------------------------------------------------
1 | import { GridLayoutBuilder } from './gridLayoutBuilder';
2 |
3 | export class SectionBuilder {
4 | parrentBuilder;
5 | grid;
6 | allowed;
7 |
8 | constructor(parrentBuilder: GridLayoutBuilder) {
9 | this.parrentBuilder = parrentBuilder;
10 | this.allowed = [];
11 | }
12 |
13 | withGridSize(gridSize: number) {
14 | this.grid = gridSize;
15 | return this;
16 | }
17 |
18 | withAllowAll() {
19 | this.allowed = [];
20 | return this;
21 | }
22 |
23 | withAllowed(allowedName: string) {
24 | this.allowed.push(allowedName);
25 | return this;
26 | }
27 |
28 | done(): GridLayoutBuilder {
29 | return this.parrentBuilder;
30 | }
31 |
32 | build() {
33 | const grid = {
34 | grid: this.grid,
35 | allowAll: true,
36 | };
37 |
38 | if (this.allowed.length > 0) {
39 | Object.assign(grid, { allowed: this.allowed });
40 | grid.allowAll = false;
41 | }
42 |
43 | return grid;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/cms/builders/dataTypes/index.ts:
--------------------------------------------------------------------------------
1 | export { FormPickerDataTypeBuilder } from './formPickerDataTypeBuilder';
2 | export { LabelDataTypeBuilder } from './labelDataTypeBuilder';
3 | export { TextBoxDataTypeBuilder } from './textBoxDataTypeBuilder';
4 | export { DropDownDataTypeBuilder } from './dropDownDataTypeBuilder';
5 | export { GridDataTypeBuilder } from './gridDataTypeBuilder';
6 |
--------------------------------------------------------------------------------
/src/cms/builders/dataTypes/labelDataTypeBuilder.ts:
--------------------------------------------------------------------------------
1 | import { DataTypeBuilder } from './dataTypeBuilder';
2 | import { LabelDataType } from '../../models/dataTypes/labelDataType';
3 |
4 | export class LabelDataTypeBuilder extends DataTypeBuilder {
5 | constructor(private labelDataType: LabelDataType = new LabelDataType()) {
6 | super(labelDataType);
7 | this.withStringValueType();
8 | }
9 |
10 | withStringValueType() {
11 | return this.withValueType('STRING');
12 | }
13 |
14 | withDecimalValueType() {
15 | return this.withValueType('DECIMAL');
16 | }
17 |
18 | withDateTimeValueType() {
19 | return this.withValueType('DATETIME');
20 | }
21 |
22 | withTimeValueType() {
23 | return this.withValueType('TIME');
24 | }
25 |
26 | withIntegerValueType() {
27 | return this.withValueType('INT');
28 | }
29 |
30 | withBigIntegerValueType() {
31 | return this.withValueType('BIGINT');
32 | }
33 |
34 | withLongStringValueType() {
35 | return this.withValueType('TEXT');
36 | }
37 |
38 | withValueType(type) {
39 | this.labelDataType.addPrevalues(type);
40 | return this;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/cms/builders/dataTypes/textBoxDataTypeBuilder.ts:
--------------------------------------------------------------------------------
1 | import { DataTypeBuilder } from './dataTypeBuilder';
2 | import { TextBoxDataType } from '../../models/dataTypes/textBoxDataType';
3 |
4 | export class TextBoxDataTypeBuilder extends DataTypeBuilder {
5 | constructor(private textBoxDataType: TextBoxDataType = new TextBoxDataType()) {
6 | super(textBoxDataType);
7 | }
8 | withMaxChars(chars: number) {
9 | this.textBoxDataType.addPrevalues(chars);
10 | return this;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/cms/builders/documentTypes/documentTypeTabBuilder.ts:
--------------------------------------------------------------------------------
1 | import DocumentTypeGroupBuilder from "./documentTypeGroupBuilder";
2 | import faker from 'faker';
3 |
4 | export default class DocumentTypeTabBuilder extends DocumentTypeGroupBuilder {
5 | documentTypeGroupBuilders;
6 |
7 | constructor(parentBuilder) {
8 | super(parentBuilder);
9 | this.documentTypeGroupBuilders = [];
10 | }
11 |
12 | addGroup(documentTypeGroupBuilder?: DocumentTypeGroupBuilder) {
13 | const builder =
14 | documentTypeGroupBuilder === null || documentTypeGroupBuilder === undefined
15 | ? new DocumentTypeGroupBuilder(this)
16 | : documentTypeGroupBuilder;
17 | this.documentTypeGroupBuilders.push(builder);
18 | return builder;
19 | }
20 |
21 | done(){
22 | this.documentTypeGroupBuilders.forEach(element => {
23 | element.alias = this.getAlias() + "/" + element.getAlias();
24 | this.parentBuilder.documentTypeGroupBuilders.push(element);
25 | });
26 | return this.parentBuilder;
27 | }
28 |
29 | build(){
30 | const name = this.name || faker.random.uuid()
31 | return {
32 | id: this.id || -1,
33 | inherited: this.inherited || false,
34 | name: this.name || name,
35 | alias: this.getAlias(),
36 | sortOrder: this.sortOrder || 0,
37 | type : 1,
38 | properties: this.documentTypeGroupPropertyBuilders.map((builder) => {
39 | return builder.build();
40 | }),
41 | };
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/cms/builders/documentTypes/index.ts:
--------------------------------------------------------------------------------
1 | export { DocumentTypeBuilder } from './documentTypeBuilder';
2 |
--------------------------------------------------------------------------------
/src/cms/builders/documentTypes/properties/approvedColorPickerTypeDataTypeBuilder.ts:
--------------------------------------------------------------------------------
1 | import { ApprovedColourPickerDataType } from 'src/cms/models/dataTypes/approvedColourPickerDataType';
2 | import { DataTypeBuilder } from '../../dataTypes/dataTypeBuilder';
3 |
4 | export class ApprovedColorPickerDataTypeBuilder extends DataTypeBuilder {
5 | constructor(private approvedColourPickerDataTypeBuilder: ApprovedColourPickerDataType = new ApprovedColourPickerDataType()) {
6 | super(approvedColourPickerDataTypeBuilder)
7 | }
8 |
9 | withPrevalues(value: string[], multiSelect = false) {
10 | this.approvedColourPickerDataTypeBuilder.addPrevalues(value, multiSelect);
11 | return this;
12 | }
13 | }
--------------------------------------------------------------------------------
/src/cms/builders/documentTypes/properties/contentPickerTypePropertyBuilder.ts:
--------------------------------------------------------------------------------
1 | import { DocumentTypePropertyBuilder } from './documentTypePropertyBuilder';
2 |
3 | export class ContentPickerPropertyBuilder extends DocumentTypePropertyBuilder {
4 | constructor(parentBuilder) {
5 | super(parentBuilder);
6 | this.dataTypeId = 1046;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/cms/builders/documentTypes/properties/customDocumentTypePropertyBuilder.ts:
--------------------------------------------------------------------------------
1 | import { DocumentTypePropertyBuilder } from './documentTypePropertyBuilder';
2 |
3 | export class CustomDocumentTypePropertyBuilder extends DocumentTypePropertyBuilder {
4 | constructor(parentBuilder, dataTypeId) {
5 | super(parentBuilder);
6 | this.dataTypeId = dataTypeId;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/cms/builders/documentTypes/properties/documentTypePropertyBuilder.ts:
--------------------------------------------------------------------------------
1 | import faker from 'faker';
2 | import camelize from 'camelize';
3 | import { AliasHelper } from '../../../../helpers/aliasHelper';
4 |
5 | export class DocumentTypePropertyBuilder {
6 | parentBuilder;
7 |
8 | alias;
9 | value;
10 | allowCultureVariant;
11 | dataTypeId;
12 | label;
13 | sortOrder;
14 | validation;
15 |
16 | constructor(parentBuilder) {
17 | this.parentBuilder = parentBuilder;
18 | }
19 |
20 | withDataTypeId(dataTypeId) {
21 | this.dataTypeId = dataTypeId;
22 | return this;
23 | }
24 | withLabel(label) {
25 | this.label = label;
26 | return this;
27 | }
28 | withAlias(alias) {
29 | this.alias = alias;
30 | return this;
31 | }
32 | withValue(value) {
33 | this.value = value;
34 | return this;
35 | }
36 | done() {
37 | return this.parentBuilder;
38 | }
39 |
40 | build() {
41 | const label = this.label || faker.random.uuid();
42 | const alias = this.alias || 'a' + camelize(label);
43 |
44 | return {
45 | alias,
46 | value: this.value || '',
47 | allowCultureVariant: this.allowCultureVariant || false,
48 | dataTypeId: this.dataTypeId || -1,
49 | label,
50 | sortOrder: this.sortOrder || 0,
51 | validation: this.validation || { mandatory: false, pattern: null },
52 | };
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/cms/builders/documentTypes/properties/dropDownDocumentTypePropertyBuilder.ts:
--------------------------------------------------------------------------------
1 | import { DocumentTypePropertyBuilder } from './documentTypePropertyBuilder';
2 |
3 | export class DropDownDocumentTypePropertyBuilder extends DocumentTypePropertyBuilder {
4 | constructor(parentBuilder) {
5 | super(parentBuilder);
6 | this.dataTypeId = -39;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/cms/builders/documentTypes/properties/formPickerDocumentTypePropertyBuilder.ts:
--------------------------------------------------------------------------------
1 | import { DocumentTypePropertyBuilder } from './documentTypePropertyBuilder';
2 |
3 | export class FormPickerDocumentTypePropertyBuilder extends DocumentTypePropertyBuilder {
4 | constructor(parentBuilder) {
5 | super(parentBuilder);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/cms/builders/documentTypes/properties/index.ts:
--------------------------------------------------------------------------------
1 | export { FormPickerDocumentTypePropertyBuilder } from './formPickerDocumentTypePropertyBuilder';
2 | export { TextBoxDocumentTypePropertyBuilder } from './textBoxDocumentTypePropertyBuilder';
3 | export { DropDownDocumentTypePropertyBuilder } from './dropDownDocumentTypePropertyBuilder';
4 | export { ContentPickerPropertyBuilder } from './contentPickerTypePropertyBuilder';
5 | export { RichTextDocumentTypePropertyEditor } from './richTextDocumentTypePropertyBuilder';
6 | export { CustomDocumentTypePropertyBuilder } from './customDocumentTypePropertyBuilder';
7 |
--------------------------------------------------------------------------------
/src/cms/builders/documentTypes/properties/richTextDocumentTypePropertyBuilder.ts:
--------------------------------------------------------------------------------
1 | import { DocumentTypePropertyBuilder } from './documentTypePropertyBuilder';
2 |
3 | export class RichTextDocumentTypePropertyEditor extends DocumentTypePropertyBuilder {
4 | constructor(parentBuilder) {
5 | super(parentBuilder);
6 | this.dataTypeId = -87;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/cms/builders/documentTypes/properties/textBoxDocumentTypePropertyBuilder.ts:
--------------------------------------------------------------------------------
1 | import { DocumentTypePropertyBuilder } from './documentTypePropertyBuilder';
2 |
3 | export class TextBoxDocumentTypePropertyBuilder extends DocumentTypePropertyBuilder {
4 | constructor(parentBuilder) {
5 | super(parentBuilder);
6 | this.dataTypeId = -88;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/cms/builders/documentTypes/properties/urlPickerTypePropertyBuilder.ts:
--------------------------------------------------------------------------------
1 | import { DocumentTypePropertyBuilder } from './documentTypePropertyBuilder';
2 |
3 | export class UrlPickerPropertyBuilder extends DocumentTypePropertyBuilder {
4 | constructor(parentBuilder) {
5 | super(parentBuilder);
6 | this.dataTypeId = 1050;
7 | }
8 | }
--------------------------------------------------------------------------------
/src/cms/builders/index.ts:
--------------------------------------------------------------------------------
1 | export { ContentBuilder } from './content/contentBuilder';
2 | export { ContentVariantBuilder } from './content/contentVariantBuilder';
3 | export { ContentVariantPropertyBuilder } from './content/contentVariantPropertyBuilder';
4 |
5 | export { FormPickerDataTypeBuilder } from './dataTypes/formPickerDataTypeBuilder';
6 | export { LabelDataTypeBuilder } from './dataTypes/labelDataTypeBuilder';
7 | export { TextBoxDataTypeBuilder } from './dataTypes/textBoxDataTypeBuilder';
8 | export { DropDownDataTypeBuilder } from './dataTypes/dropDownDataTypeBuilder';
9 |
10 | export { DocumentTypeBuilder } from './documentTypes/documentTypeBuilder';
11 |
12 | export { TemplateBuilder } from './templates/templateBuilder';
13 |
14 | export { UserGroupBuilder } from './userGroups/userGroupBuilder';
15 | export { UserBuilder } from './user/userBuilder';
16 | export { MediaBuilder } from './media'
--------------------------------------------------------------------------------
/src/cms/builders/macroBuilder.ts:
--------------------------------------------------------------------------------
1 | import { AliasHelper } from '../../helpers/aliasHelper';
2 |
3 | export class MacroBuilder {
4 | name;
5 | renderInEditor;
6 | useInEditor;
7 | cacheByPage;
8 | cacheByUser;
9 | partialViewMacro;
10 |
11 | withName(name) {
12 | this.name = name;
13 | return this;
14 | }
15 |
16 | withRenderInEditor() {
17 | this.renderInEditor = true;
18 | return this;
19 | }
20 |
21 | withUseInEditor() {
22 | this.useInEditor = true;
23 | return this;
24 | }
25 |
26 | withCacheByPage() {
27 | this.cacheByPage = true;
28 | return this;
29 | }
30 |
31 | withCacheByUser() {
32 | this.cacheByUser = true;
33 | return this;
34 | }
35 |
36 | withPartialViewMacro(partialView) {
37 | this.partialViewMacro = partialView;
38 | return this;
39 | }
40 |
41 | build() {
42 | return {
43 | name: this.name,
44 | renderInEditor: this.renderInEditor || true,
45 | useInEditor: this.useInEditor || false,
46 | cacheByPage: this.cacheByPage || false,
47 | cacheByUser: this.cacheByUser || false,
48 | partialView: this.partialViewMacro || null,
49 | };
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/cms/builders/media/index.ts:
--------------------------------------------------------------------------------
1 | export { MediaBuilder } from './mediaBuilder';
2 | export { MediaPropertyBuilder } from './mediaPropertyBuilder';
3 |
--------------------------------------------------------------------------------
/src/cms/builders/media/mediaBuilder.ts:
--------------------------------------------------------------------------------
1 | import {MediaPropertyBuilder} from './mediaPropertyBuilder';
2 |
3 | export class MediaBuilder {
4 | id;
5 | properties;
6 | name;
7 | contentTypeAlias;
8 | parentId;
9 | action;
10 | mediaPropertyBuilder;
11 |
12 | constructor() {
13 | this.mediaPropertyBuilder = [];
14 | }
15 |
16 | addProperty() {
17 | const builder = new MediaPropertyBuilder(this);
18 | this.mediaPropertyBuilder.push(builder);
19 | return builder;
20 | }
21 |
22 | withName(name) {
23 | this.name = name;
24 | return this;
25 | }
26 |
27 | withContentTypeAlias(contentTypeAlias) {
28 | this.contentTypeAlias = contentTypeAlias;
29 | return this;
30 | }
31 |
32 | build() {
33 | return {
34 | id: this.id || '0',
35 | properties: this.mediaPropertyBuilder.map((builder) => {
36 | return builder.build();
37 | }),
38 | name: this.name,
39 | contentTypeAlias: this.contentTypeAlias,
40 | parentId: this.parentId || '-1',
41 | action: this.action || 'saveNew'
42 | };
43 | }
44 | }
--------------------------------------------------------------------------------
/src/cms/builders/media/mediaPropertyBuilder.ts:
--------------------------------------------------------------------------------
1 | export class MediaPropertyBuilder {
2 | parentBuilder;
3 | id;
4 | alias;
5 | value;
6 |
7 | constructor(parentBuilder) {
8 | this.parentBuilder = parentBuilder;
9 | }
10 |
11 | withAlias(alias) {
12 | this.alias = alias;
13 | return this;
14 | }
15 |
16 | withValue(value) {
17 | this.value = value;
18 | return this;
19 | }
20 |
21 | done() {
22 | return this.parentBuilder;
23 | }
24 |
25 | build() {
26 | return {
27 | id: this.id || 0,
28 | alias: this.alias || null,
29 | value: this.value || null,
30 | };
31 | }
32 | }
--------------------------------------------------------------------------------
/src/cms/builders/partialViewMacros/partialViewMacroBuilder.ts:
--------------------------------------------------------------------------------
1 | import { PartialViewMacro } from '../../models/partialViewMacros/partialViewMacro';
2 |
3 | export class PartialViewMacroBuilder {
4 | constructor(public partialViewMacro: PartialViewMacro = new PartialViewMacro()) {}
5 |
6 | public withName(name) {
7 | this.partialViewMacro.name = name;
8 | return this;
9 | }
10 | public withContent(content) {
11 | this.partialViewMacro.content = content;
12 | return this;
13 | }
14 |
15 | public build(): PartialViewMacro {
16 | return this.partialViewMacro;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/cms/builders/partialViews/partialViewBuilder.ts:
--------------------------------------------------------------------------------
1 | export class PartialViewBuilder {
2 | name;
3 | content;
4 | filetype;
5 | id;
6 | notifications;
7 | path;
8 | snippet;
9 | virtualPath;
10 |
11 | withContent(content) {
12 | this.content = content;
13 | return this;
14 | }
15 |
16 | withName(name) {
17 | this.name = name;
18 | return this;
19 | }
20 |
21 | withId(id: number) {
22 | this.id = id;
23 | return this;
24 | }
25 |
26 | build() {
27 | return {
28 | name: this.name,
29 | content: this.content,
30 | filetype: this.filetype || 'partialViews',
31 | id: this.id || 0,
32 | notifications: this.notifications || [],
33 | path: this.path || null,
34 | snippet: this.snippet || null,
35 | virtualPath: this.virtualPath || '/Views/Partials/',
36 | };
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/cms/builders/scriptbuilder.ts:
--------------------------------------------------------------------------------
1 | export class ScriptBuilder {
2 | content;
3 | fileType;
4 | id;
5 | name;
6 | notifications;
7 | path;
8 | snippet;
9 | virtualPath;
10 |
11 | withContent(content) {
12 | this.content = content;
13 | return this;
14 | }
15 |
16 | withName(name) {
17 | this.name = name;
18 | return this;
19 | }
20 |
21 | build() {
22 | return {
23 | name: this.name,
24 | content: this.content,
25 | filetype: this.fileType || 'scripts',
26 | id: this.id || '0',
27 | notifications: this.notifications || [],
28 | path: this.path || null,
29 | snippet: this.snippet || null,
30 | virtualPath: this.virtualPath || '/scripts/',
31 | };
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/cms/builders/stylesheetBuilder.ts:
--------------------------------------------------------------------------------
1 | export class StylesheetBuilder {
2 | content;
3 | fileType;
4 | id;
5 | name;
6 | notifications;
7 | path;
8 | snippet;
9 | virtualPath;
10 |
11 | withContent(content) {
12 | this.content = content;
13 | return this;
14 | }
15 |
16 | withName(name) {
17 | this.name = name;
18 | return this;
19 | }
20 |
21 | build() {
22 | return {
23 | name: this.name,
24 | content: this.content,
25 | filetype: this.fileType || 'stylesheets',
26 | id: this.id || '0',
27 | notifications: this.notifications || [],
28 | path: this.path || null,
29 | snippet: this.snippet || null,
30 | virtualPath: this.virtualPath || '/css/',
31 | };
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/cms/builders/templates/index.ts:
--------------------------------------------------------------------------------
1 | export { TemplateBuilder } from './templateBuilder';
2 |
--------------------------------------------------------------------------------
/src/cms/builders/templates/templateBuilder.ts:
--------------------------------------------------------------------------------
1 | import { Template } from '../../models/template';
2 |
3 | export class TemplateBuilder {
4 | constructor(private template: Template = new Template()) {}
5 |
6 | withId(id) {
7 | this.template.id = id;
8 | return this;
9 | }
10 | withKey(key) {
11 | this.template.key = key;
12 | return this;
13 | }
14 | withName(name) {
15 | this.template.name = name;
16 | return this;
17 | }
18 | withAlias(alias) {
19 | this.template.alias = alias;
20 | return this;
21 | }
22 | withContent(content) {
23 | this.template.content = content;
24 | return this;
25 | }
26 | withPath(path) {
27 | this.template.path = path;
28 | return this;
29 | }
30 | withVirtualPath(virtualPath) {
31 | this.template.virtualPath = virtualPath;
32 | return this;
33 | }
34 | withMasterTemplateAlias(masterTemplateAlias) {
35 | this.template.masterTemplateAlias = masterTemplateAlias;
36 | return this;
37 | }
38 | withIsMasterTemplate(isMasterTemplate) {
39 | this.template.isMasterTemplate = isMasterTemplate;
40 | return this;
41 | }
42 | withNotifications(notifications) {
43 | this.template.notifications = notifications;
44 | return this;
45 | }
46 |
47 | public build(): Template {
48 | return this.template;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/cms/builders/user/index.ts:
--------------------------------------------------------------------------------
1 | export { UserBuilder } from './userBuilder';
--------------------------------------------------------------------------------
/src/cms/builders/user/userBuilder.ts:
--------------------------------------------------------------------------------
1 | import faker from 'faker';
2 |
3 | export class UserBuilder {
4 | email: string;
5 | id: number;
6 | message: string;
7 | name: string;
8 | parentId: number;
9 | userGroups: string[];
10 |
11 |
12 | constructor() {
13 | this.userGroups = [];
14 | }
15 |
16 | withEmail(email: string) {
17 | this.email = email;
18 | return this;
19 | }
20 |
21 | withId(id: number) {
22 | this.id = id;
23 | return this;
24 | }
25 |
26 | withName(name: string) {
27 | this.name = name;
28 | return this;
29 | }
30 |
31 | withParentId(parentId: number) {
32 | this.parentId = parentId;
33 | return this;
34 | }
35 |
36 | appendUserGroup(userGroup: string) {
37 | this.userGroups.push(userGroup);
38 | return this;
39 | }
40 |
41 | withUserGroups(userGroups: string[]) {
42 | this.userGroups = userGroups;
43 | return this;
44 | }
45 |
46 | build() {
47 | const email = this.email || 'test@test.com';
48 | return {
49 | email: email,
50 | id: this.id || -1,
51 | message: this.message || "",
52 | name: this.name || email,
53 | parentId: this.parentId || -1,
54 | userGroups: this.userGroups || []
55 | };
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/cms/builders/userGroups/index.ts:
--------------------------------------------------------------------------------
1 | export { UserGroupBuilder } from './userGroupBuilder';
--------------------------------------------------------------------------------
/src/cms/builders/userGroups/nodePermissionBuilder.ts:
--------------------------------------------------------------------------------
1 | import {PermissionsBuilder} from "./permissionsBuilder";
2 |
3 | export class NodePermissionBuilder extends PermissionsBuilder {
4 | nodeId: number;
5 |
6 | constructor(parentBuilder) {
7 | super(parentBuilder);
8 | }
9 |
10 | withNodeId(nodeId: number) {
11 | this.nodeId = nodeId;
12 | return this;
13 | }
14 |
15 | build(): any {
16 | const permissions = super.build();
17 |
18 | // Programatically assigns a property with the nodeId, I.E {123: ["S"...]} where 123 is the ID.
19 | // It's important that enumerable is true, otherwise the property will not be serialized in the final result.
20 | let result = {};
21 | result = Object.defineProperty(result, this.nodeId, {
22 | value: permissions,
23 | configurable: true,
24 | writable: true,
25 | enumerable: true
26 | });
27 |
28 | return result;
29 | }
30 | }
--------------------------------------------------------------------------------
/src/cms/builders/userGroups/nodePermissionCollectionBuilder.ts:
--------------------------------------------------------------------------------
1 | import {NodePermissionBuilder} from "./nodePermissionBuilder";
2 |
3 | export class NodePermissionCollectionBuilder{
4 | nodePermissionBuilders: NodePermissionBuilder[];
5 | parentBuilder;
6 |
7 | constructor(parentBuilder) {
8 | this.nodePermissionBuilders = [];
9 | this.parentBuilder = parentBuilder;
10 | }
11 |
12 | addNodePermission(nodePermissionBuilder ?: NodePermissionBuilder) {
13 | const builder =
14 | nodePermissionBuilder === null || nodePermissionBuilder == undefined
15 | ? new NodePermissionBuilder(this)
16 | : nodePermissionBuilder;
17 |
18 | this.nodePermissionBuilders.push(builder);
19 | return builder;
20 | }
21 |
22 | done() {
23 | return this.parentBuilder
24 | }
25 |
26 | build() {
27 | let result = {};
28 |
29 | // Each NodePermission builder returns an object, with the node ID as property key and the permission array as value
30 | // we need to merge all of these to a single object the backend will accept.
31 | this.nodePermissionBuilders.forEach((builder) => {
32 | result = Object.assign(result, builder.build());
33 | })
34 |
35 | return result;
36 | }
37 | }
--------------------------------------------------------------------------------
/src/cms/models/cmsDocumentType.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * An Umbraco Document Type
3 | *
4 | * @param {string} name Name of Document Type
5 | * @param {string} alias Alias of Document type
6 | * @param {number} id Optional integer ID of document type
7 | */
8 | export class CmsDocumentType {
9 | constructor(public name: string, public alias: string, public id?: number) {}
10 | }
11 |
--------------------------------------------------------------------------------
/src/cms/models/dataTypes/approvedColourPickerDataType.ts:
--------------------------------------------------------------------------------
1 | import { DataType } from './dataType';
2 |
3 | export class ApprovedColourPickerDataType extends DataType {
4 | constructor() {
5 | super();
6 | this.selectedEditor = 'Umbraco.ColorPicker';
7 | this.addPrevalues([], false);
8 |
9 | }
10 | public addPrevalues(value: string[], multiSelect = false) {
11 | this.preValues = [
12 | { key: 'useLabel', value: multiSelect },
13 | {
14 | key: 'items',
15 | value: value.map((val) => {
16 | return { value: val };
17 | }),
18 | },
19 | ];
20 | }
21 | }
--------------------------------------------------------------------------------
/src/cms/models/dataTypes/checkBoxListDataType.ts:
--------------------------------------------------------------------------------
1 | import { DataType } from './dataType';
2 |
3 | export class CheckBoxListDataType extends DataType {
4 | constructor() {
5 | super();
6 | this.selectedEditor = 'Umbraco.CheckBoxList';
7 | this.addPrevalues([], false);
8 | }
9 | public addPrevalues(value: string[], multiSelect = false) {
10 | this.preValues = [
11 | { key: 'multiple', value: multiSelect },
12 | {
13 | key: 'items',
14 | value: value.map((val) => {
15 | return { value: val };
16 | }),
17 | },
18 | ];
19 | }
20 | }
--------------------------------------------------------------------------------
/src/cms/models/dataTypes/dataType.ts:
--------------------------------------------------------------------------------
1 | import { DataTypePrevalue } from './dataTypePrevalue';
2 |
3 | export abstract class DataType {
4 | public action = 'saveNew';
5 | public id = 0;
6 | public name = '';
7 | public parentId = -1;
8 | public selectedEditor = '';
9 | protected preValues: DataTypePrevalue[];
10 |
11 | public getPrevalues() {
12 | return this.preValues;
13 | }
14 | public abstract addPrevalues(value: any[] | any);
15 | }
16 |
--------------------------------------------------------------------------------
/src/cms/models/dataTypes/dataTypePrevalue.ts:
--------------------------------------------------------------------------------
1 | export class DataTypePrevalue {
2 | key: string;
3 | value: any[] | any;
4 | }
5 |
--------------------------------------------------------------------------------
/src/cms/models/dataTypes/dropDownDataType.ts:
--------------------------------------------------------------------------------
1 | import { DataType } from './dataType';
2 |
3 | export class DropDownDataType extends DataType {
4 | constructor() {
5 | super();
6 | this.selectedEditor = 'Umbraco.DropDown.Flexible';
7 | this.addPrevalues([], false);
8 | }
9 | public addPrevalues(value: string[], multiSelect = false) {
10 | this.preValues = [
11 | { key: 'multiple', value: multiSelect },
12 | {
13 | key: 'items',
14 | value: value.map((val) => {
15 | return { value: val };
16 | }),
17 | },
18 | ];
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/cms/models/dataTypes/formPickerDataType.ts:
--------------------------------------------------------------------------------
1 | import { DataType } from './dataType';
2 |
3 | export class FormPickerDataType extends DataType {
4 | constructor() {
5 | super();
6 | this.selectedEditor = 'UmbracoForms.FormPicker';
7 | this.addPrevalues([]);
8 | }
9 | public addPrevalues(value: any[]) {
10 | this.preValues = [{ key: 'allowedForms', value }];
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/cms/models/dataTypes/gridDataType.ts:
--------------------------------------------------------------------------------
1 | import { DataType } from './dataType';
2 | import { DataTypePrevalue } from './dataTypePrevalue';
3 |
4 | export class GridDataType extends DataType {
5 | constructor() {
6 | super();
7 | this.selectedEditor = 'Umbraco.Grid';
8 | }
9 |
10 | public addPrevalues(values: DataTypePrevalue[]) {
11 | this.preValues = values;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/cms/models/dataTypes/index.ts:
--------------------------------------------------------------------------------
1 | export { DataType } from './dataType';
2 | export { DataTypePrevalue } from './dataTypePrevalue';
3 | export { FormPickerDataType } from './formPickerDataType';
4 | export { LabelDataType } from './labelDataType';
5 | export { TextBoxDataType } from './textBoxDataType';
6 | export { DropDownDataType } from './dropDownDataType';
7 | export { GridDataType } from './gridDataType';
8 |
--------------------------------------------------------------------------------
/src/cms/models/dataTypes/labelDataType.ts:
--------------------------------------------------------------------------------
1 | import { DataType } from './dataType';
2 |
3 | export class LabelDataType extends DataType {
4 | constructor() {
5 | super();
6 | this.selectedEditor = 'Umbraco.Label';
7 | this.addPrevalues('');
8 | }
9 | public addPrevalues(value: string) {
10 | this.preValues = [{ key: 'umbracoDataValueType', value: [value] }];
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/cms/models/dataTypes/textBoxDataType.ts:
--------------------------------------------------------------------------------
1 | import { DataType } from './dataType';
2 |
3 | export class TextBoxDataType extends DataType {
4 | constructor() {
5 | super();
6 | this.selectedEditor = 'Umbraco.TextBox';
7 | this.addPrevalues(8);
8 | }
9 | public addPrevalues(maxChars: number) {
10 | this.preValues = [{ key: 'maxChars', value: maxChars }];
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/cms/models/index.ts:
--------------------------------------------------------------------------------
1 | export * from './dataTypes';
2 | export * from './properties';
3 | export { Template } from './template';
4 | export { CmsDocumentType } from './cmsDocumentType';
5 |
--------------------------------------------------------------------------------
/src/cms/models/partialViewMacros/partialViewMacro.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Used to generate a new PartialViewMacro
3 | */
4 | export class PartialViewMacro {
5 | public name = '';
6 | public content = '';
7 | public fileType = 'partialViewMacros';
8 | public notifications = [];
9 | public path = null;
10 | public id = 0;
11 | public snippet = null;
12 | public virtualPath = '/Views/MacroPartials/';
13 | }
14 |
--------------------------------------------------------------------------------
/src/cms/models/properties/baseProperty.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Creates a property object used in document types etc
3 | *
4 | * @param {string} name Name of the property
5 | * @param {string} alias Optional alias of the property
6 | */
7 | export class BaseProperty {
8 | public id: string;
9 | public alias: string;
10 | public name: string;
11 | constructor(name: string, alias?: string) {
12 | this.alias = alias;
13 | this.name = name;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/cms/models/properties/dropDownProperty.ts:
--------------------------------------------------------------------------------
1 | import { BaseProperty } from './baseProperty';
2 |
3 | /**
4 | * @param {string} name Property name
5 | * @param {string} alias Property alias
6 | * @param {boolean} multiSelect Bool if Dropdown values can be multi selected
7 | * @param {string[]} values Optional string array of values in the dropdown
8 | */
9 | export class DropDownProperty extends BaseProperty {
10 | public values: string[];
11 | public multiSelect: boolean;
12 | constructor(name: string, alias: string, multiSelect = false, values?: string[]) {
13 | super(name, alias);
14 | this.values = values;
15 | this.multiSelect = multiSelect;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/cms/models/properties/formPickerProperty.ts:
--------------------------------------------------------------------------------
1 | import { BaseProperty } from './baseProperty';
2 |
3 | /**
4 | * @param {string} name Property name
5 | * @param {string} alias Property alias
6 | * @param {string} value Property value of form picker - this stores a UUID of the picked form ID/key
7 | * @param {string[]} allowedFormIds Optional string array of UUIDs of form ID/keys that are allowed to be picked
8 | */
9 | export class FormPickerProperty extends BaseProperty {
10 | allowedFormIds: string[];
11 | value: string;
12 | constructor(name: string, alias: string, value: string, allowedFormIds?: string[]) {
13 | super(name, alias);
14 | this.allowedFormIds = allowedFormIds;
15 | this.value = value;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/cms/models/properties/index.ts:
--------------------------------------------------------------------------------
1 | export { TextBoxProperty } from './textBoxProperty';
2 | export { FormPickerProperty } from './formPickerProperty';
3 | export { DropDownProperty } from './dropDownProperty';
4 |
--------------------------------------------------------------------------------
/src/cms/models/properties/textBoxProperty.ts:
--------------------------------------------------------------------------------
1 | import { BaseProperty } from './baseProperty';
2 |
3 | export class TextBoxProperty extends BaseProperty {
4 | public value: string;
5 | public maxChars: number;
6 | constructor(name: string, alias: string, maxChars: number, value?: string) {
7 | super(name, alias);
8 | this.value = value;
9 | this.maxChars = maxChars;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/cms/models/template.ts:
--------------------------------------------------------------------------------
1 | import faker from 'faker';
2 | import camelize from 'camelize';
3 |
4 | /**
5 | * Used to generate a new template
6 | * Will generate name, key and alias and virtualPath for view as random UUID
7 | *
8 | */
9 | export class Template {
10 | public id = 0;
11 | public name: string = faker.random.uuid();
12 | public key: string = faker.random.uuid();
13 | public alias: string = 'a' + camelize(name);
14 | public virtualPath: string = '/Views/' + this.alias + '.cshtml';
15 | public content =
16 | '@inherits Umbraco.Web.Mvc.UmbracoViewPage\r\n@{\r\n\tLayout = null;\r\n}\r\n\r\n@* the fun starts here *@\r\n\r\n';
17 | public masterTemplateAlias: string = null;
18 | public path = '-1';
19 | public isMasterTemplate = false;
20 | public notifications = null;
21 | }
22 |
--------------------------------------------------------------------------------
/src/cms/templates/formPickerTemplate.ts:
--------------------------------------------------------------------------------
1 | import { AliasHelper } from '../../helpers/aliasHelper';
2 |
3 | export class FormPickerTemplate {
4 | /**
5 | * Generates a HTML Razor View to use with Umbraco Forms.
6 | * Adds the Umbraco Forms Macro to the template with the
7 | *
8 | * @param {string} formPickerModel Doctype Property Name that contains the Form Picker
9 | * @param {string} model Name of model to use in HTML Razor View template. Default value is empty string
10 | * @param {{name:string;alias:string}[]} properties Optional array of objects containing `name` and `alias` which will use to print out the Document type property values in the view
11 | * @returns string A basic HTML Razor view with Umbraco Forms macro added to the page, with the correct model for the doctype and prints out values for each property
12 | */
13 | public get(formPickerModel: string, model = '', properties?: { name: string; alias: string }[]): string {
14 | if (model.length > 0) model = `<${AliasHelper.capitalize(model)}>`;
15 | let template = `@inherits Umbraco.Web.Mvc.UmbracoViewPage${model}\n
16 | @using ContentModels = Umbraco.Web.PublishedModels;\n
17 | @{\n
18 | \tLayout = null;\n
19 | }\n
20 | \n
21 | \t
\n
22 | \t\t\n
23 | \t\t\n
24 | \t\t\n
25 | \t\n
26 | \t\n`;
27 | properties?.forEach((property) => {
28 | template += `@Model.Value("${property.alias}")\n`;
29 | });
30 | template += `\t\t@Umbraco.RenderMacro("renderUmbracoForm", new {FormGuid=Model.${formPickerModel}.ToString(), FormTheme="", ExcludeScripts="0"})`;
31 | template += ` \t\n
32 | \n `;
33 | return template;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/cms/templates/index.ts:
--------------------------------------------------------------------------------
1 | export { FormPickerTemplate } from './formPickerTemplate';
2 | export { MinimalTemplate } from './minimalTemplate';
3 |
--------------------------------------------------------------------------------
/src/cms/templates/minimalTemplate.ts:
--------------------------------------------------------------------------------
1 | import { AliasHelper } from '../../helpers/aliasHelper';
2 |
3 | export class MinimalTemplate {
4 | /**
5 | * Generates a HTML string for a basic HTML Razor view template
6 | *
7 | * @param {string} model Name of model to use in HTML Razor View template. Default value is empty string
8 | * @param {{name:string;alias:string}[]} properties Optional array of objects containing `name` and `alias` which will use to print out the Document type property values in the view
9 | * @returns string A basic HTML Razor view with the correct model for the doctype and prints out values for each property
10 | */
11 | public get(model = '', properties?: { name: string; alias: string }[]): string {
12 | if (model.length > 0) model = `<${AliasHelper.capitalize(model)}>`;
13 | let template = `@inherits Umbraco.Web.Mvc.UmbracoViewPage${model}
14 | @{
15 | Layout = null;
16 | }
17 | `;
18 | if (properties?.length > 0) {
19 | properties.forEach((property) => {
20 | template += `@Model.Value("${property.alias}")\n`;
21 | });
22 | }
23 |
24 | return template;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/cypress/commands/commandBase.ts:
--------------------------------------------------------------------------------
1 | export default class CommandBase {
2 | _commandName;
3 | _relativeBackOfficePath;
4 | _cy;
5 | _cypress;
6 |
7 | get commandName() {
8 | return this._commandName;
9 | }
10 | set commandName(commandName) {
11 | this._commandName = commandName;
12 | }
13 | get relativeBackOfficePath() {
14 | return this._relativeBackOfficePath;
15 | }
16 | get cy() {
17 | if (typeof this._cy !== 'undefined') {
18 | return this._cy;
19 | }
20 | return cy;
21 | }
22 |
23 | get cypress() {
24 | if (typeof this._cypress !== 'undefined') {
25 | return this._cypress;
26 | }
27 | return Cypress;
28 | }
29 |
30 | constructor(relativeBackOfficePath, cy?, cypress?) {
31 | this._relativeBackOfficePath = relativeBackOfficePath;
32 | this._cy = cy;
33 | this._cypress = cypress;
34 | }
35 |
36 | method(a, b, c, d, e, f, g) {
37 | throw new Error('You have to implement the method()');
38 | }
39 | getCommand() {
40 | return {
41 | name: this.commandName,
42 | method: (a, b, c, d, e, f, g) => {
43 | this.method(a, b, c, d, e, f, g);
44 | },
45 | };
46 | }
47 | registerCommand() {
48 | this.cypress.Commands.add(this.commandName, (a, b, c, d, e, f, g) => {
49 | this.method(a, b, c, d, e, f, g);
50 | });
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/cypress/commands/cycleHackWorkaroundForPureLiveIssue.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class CycleHackWorkaroundForPureLiveIssue extends CommandBase {
4 | commandName = 'cycleHackWorkaroundForPureLiveIssue';
5 |
6 | method() {
7 | const cy = this.cy;
8 |
9 | const method = 'GET';
10 | const url = '/people'; // Nasty hack - this endpoint right now triggers a purelive reset
11 |
12 | return cy
13 | .server()
14 | .route(method, url)
15 | .as('cycleHackWorkaroundForPureLiveIssue')
16 | .window()
17 | .then((win) => {
18 | const xhr = new win.XMLHttpRequest();
19 | xhr.open(method, url);
20 | xhr.send();
21 | })
22 | .wait('@cycleHackWorkaroundForPureLiveIssue', { requestTimeout: 30000 })
23 | .wait(4000); // We know the app restart is delayed 1000
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/cypress/commands/dataUmb.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | export default class DataUmb extends CommandBase {
3 | commandName = 'dataUmb';
4 | method(value: string, child?: string) {
5 | if (child !== undefined) return cy.get(`[data-umb=${value}] ${child}`);
6 | else return cy.get(`[data-umb=${value}]`);
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/cypress/commands/dataUmbScope.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | export default class DataUmbScope extends CommandBase {
3 | commandName = 'dataUmbScope';
4 | method(value: string, child?: string) {
5 | const element = child !== undefined ? cy.dataUmb(value, child) : cy.dataUmb(value);
6 | return element.then(($el) => cy.getAngular().then((ng) => ng.element($el).scope()));
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/cypress/commands/deleteAllContent.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class DeleteAllContent extends CommandBase {
5 | commandName = 'deleteAllContent';
6 |
7 | method() {
8 | const cy = this.cy;
9 | return cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
10 | cy.request({
11 | method: 'GET',
12 | url: `${this.relativeBackOfficePath}/backoffice/UmbracoTrees/ApplicationTree/GetApplicationTrees?application=content&tree=&use=main`,
13 | headers: {
14 | 'X-UMB-XSRF-TOKEN': token.value,
15 | },
16 | }).then((response) => {
17 | const content = JsonHelper.getBody(response);
18 | for (const child of content.children) {
19 | if (child.id > 0) {
20 | cy.deleteContentById(child.id);
21 | }
22 | }
23 | return;
24 | });
25 | });
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/cypress/commands/deleteAllDataSources.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class DeleteAllDataSources extends CommandBase {
5 | commandName = 'deleteAllDataSources';
6 |
7 | method() {
8 | const cy = this.cy;
9 | return cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
10 | return cy
11 | .request({
12 | method: 'GET',
13 | url: `${this.relativeBackOfficePath}/backoffice/UmbracoForms/DataSourceTree/GetNodes?id=-1&application=forms&tree=&use=main&culture=`,
14 | headers: {
15 | 'X-UMB-XSRF-TOKEN': token.value,
16 | },
17 | })
18 | .then((response) => {
19 | const dataSources = JsonHelper.getBody(response);
20 |
21 | for (const datasource of dataSources) {
22 | cy.deleteDataSourceByGuId(datasource.id);
23 | }
24 | return;
25 | });
26 | });
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/cypress/commands/deleteAllForms.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class DeleteAllForms extends CommandBase {
5 | commandName = 'deleteAllForms';
6 |
7 | method() {
8 | const cy = this.cy;
9 | return cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
10 | return cy
11 | .request({
12 | method: 'GET',
13 | url:
14 | this.relativeBackOfficePath +
15 | '/backoffice/UmbracoForms/FormTree/GetNodes?id=-1&application=forms&tree=&use=main&culture=',
16 | headers: {
17 | 'X-UMB-XSRF-TOKEN': token.value,
18 | },
19 | })
20 | .then((response) => {
21 | const forms = JsonHelper.getBody(response);
22 |
23 | for (const form of forms) {
24 | cy.deleteFormByGuid(form.id);
25 | }
26 | return;
27 | });
28 | });
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/cypress/commands/deleteAllPreValues.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class DeleteAllPreValues extends CommandBase {
5 | commandName = 'deleteAllPreValues';
6 |
7 | method() {
8 | const cy = this.cy;
9 | return cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
10 | return cy
11 | .request({
12 | method: 'GET',
13 | url: `${this.relativeBackOfficePath}/backoffice/UmbracoForms/PreValueSourceTree/GetNodes?id=-1&application=forms&tree=&use=main&culture=`,
14 | headers: {
15 | 'X-UMB-XSRF-TOKEN': token.value,
16 | },
17 | })
18 | .then((response) => {
19 | const preValueSources = JsonHelper.getBody(response);
20 |
21 | for (const preValueSource of preValueSources) {
22 | cy.deletePreValueSourceByGuId(preValueSource.id);
23 | }
24 | return;
25 | });
26 | });
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/cypress/commands/deleteContentById.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class DeleteContentByIid extends CommandBase {
4 | commandName = 'deleteContentById';
5 |
6 | method(id) {
7 | const cy = this.cy;
8 |
9 | if (id == null) {
10 | return;
11 | }
12 |
13 | return cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
14 | return cy
15 | .request({
16 | method: 'DELETE',
17 | url: `${this.relativeBackOfficePath}/backoffice/UmbracoApi/Content/DeleteById?id=${id}`,
18 | json: true,
19 | headers: {
20 | Accept: 'application/json',
21 | 'X-UMB-XSRF-TOKEN': token.value,
22 | },
23 | })
24 | .then((resp) => {
25 | return resp;
26 | });
27 | });
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/cypress/commands/deleteDataSourceByGuid.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class DeleteDataSourceByGuid extends CommandBase {
4 | commandName = 'deleteDataSourceByGuId';
5 |
6 | method(guid) {
7 | const cy = this.cy;
8 |
9 | if (guid == null) {
10 | return;
11 | }
12 |
13 | return cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
14 | return cy
15 | .request({
16 | method: 'DELETE',
17 | url: `${this.relativeBackOfficePath}/backoffice/UmbracoForms/DataSource/DeleteByGuid?guid=${guid}`,
18 | json: true,
19 | headers: {
20 | Accept: 'application/json',
21 | 'X-UMB-XSRF-TOKEN': token.value,
22 | },
23 | })
24 | .then((resp) => {
25 | return resp;
26 | });
27 | });
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/cypress/commands/deleteDataTypeById.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class DeleteDataTypeById extends CommandBase {
5 | commandName = 'deleteDataTypeById';
6 | method(id) {
7 | const cy = this.cy;
8 |
9 | if (id == null) {
10 | return;
11 | }
12 | return cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
13 | return cy
14 | .request({
15 | method: 'POST',
16 | url: this.relativeBackOfficePath + '/backoffice/UmbracoApi/DataType/DeleteById?id=' + id,
17 | headers: {
18 | contentType: 'application/json',
19 | 'X-UMB-XSRF-TOKEN': token.value,
20 | },
21 | })
22 | .then((response) => {
23 | return response;
24 | });
25 | });
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/cypress/commands/deleteDataTypesByNamePrefix.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class DeleteDataTypesByNamePrefix extends CommandBase {
5 | commandName = 'deleteDataTypesByNamePrefix';
6 |
7 | method(prefix: string) {
8 | const cy = this.cy;
9 | return cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
10 | return cy
11 | .request({
12 | method: 'GET',
13 | url:
14 | this.relativeBackOfficePath +
15 | '/backoffice/UmbracoTrees/DataTypeTree/GetNodes?id=-1&application=settings&tree=&use=main&culture=',
16 | headers: {
17 | 'X-UMB-XSRF-TOKEN': token.value,
18 | },
19 | })
20 | .then((response) => {
21 | const items = JsonHelper.getBody(response);
22 |
23 | for (const item of items) {
24 | if (item.name.startsWith(prefix) || item.name.startsWith(prefix.toLowerCase())) {
25 | cy.deleteDataTypeById(item.id);
26 | }
27 | }
28 | return;
29 | });
30 | });
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/cypress/commands/deleteDocumentType.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class DeleteDocumentType extends CommandBase {
5 | commandName = 'deleteDocumentType';
6 |
7 | method(id) {
8 | const cy = this.cy;
9 |
10 | if (id == null) {
11 | return;
12 | }
13 |
14 | if (typeof id === 'string' || id instanceof String) {
15 | return cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
16 | return cy
17 | .request({
18 | method: 'GET',
19 | url: this.relativeBackOfficePath + '/backoffice/UmbracoApi/ContentType/GetAll',
20 | headers: {
21 | Accept: 'application/json',
22 | 'X-UMB-XSRF-TOKEN': token.value,
23 | },
24 | })
25 | .then((response) => {
26 | const documentTypes = JsonHelper.getBody(response);
27 | for (const documentType of documentTypes) {
28 | if (documentType.alias === id || documentType.key === id) {
29 | return cy.deleteDocumentTypeById(documentType.id);
30 | }
31 | }
32 | });
33 | });
34 | } else {
35 | // assume int
36 | return cy.deleteDocumentTypeById(id);
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/cypress/commands/deleteDocumentTypeById.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class DeleteDocumentTypeById extends CommandBase {
5 | commandName = 'deleteDocumentTypeById';
6 |
7 | method(id) {
8 | const cy = this.cy;
9 |
10 | if (id == null) {
11 | return;
12 | }
13 | return cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
14 | return cy
15 | .request({
16 | method: 'DELETE',
17 | url: this.relativeBackOfficePath + '/backoffice/UmbracoApi/ContentType/DeleteById?id=' + id,
18 | headers: {
19 | accept: 'application/json',
20 | 'X-UMB-XSRF-TOKEN': token.value,
21 | },
22 | })
23 | .then((response) => {
24 | return response;
25 | });
26 | });
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/cypress/commands/deleteDocumentTypesByNamePrefix.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class DeleteDocumentTypesByNamePrefix extends CommandBase {
5 | commandName = 'deleteDocumentTypesByNamePrefix';
6 |
7 | method(prefix) {
8 | const cy = this.cy;
9 | return cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
10 | return cy
11 | .request({
12 | method: 'GET',
13 | url:
14 | this.relativeBackOfficePath +
15 | '/backoffice/UmbracoTrees/ContentTypeTree/GetNodes?id=-1&application=settings&tree=&use=main&culture=',
16 | headers: {
17 | Accept: 'application/json',
18 | 'X-UMB-XSRF-TOKEN': token.value,
19 | },
20 | })
21 | .then((response) => {
22 | const items = JsonHelper.getBody(response);
23 | for (const item of items) {
24 | if (item.name?.startsWith(prefix)) cy.deleteDocumentTypeById(item.id);
25 | }
26 | return;
27 | });
28 | });
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/cypress/commands/deleteForm.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class DeleteForm extends CommandBase {
5 | commandName = 'deleteForm';
6 |
7 | method(id) {
8 | const cy = this.cy;
9 |
10 | if (id == null) {
11 | return;
12 | }
13 |
14 | if (typeof id === 'string' || id instanceof String) {
15 | return cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
16 | cy.request({
17 | method: 'GET',
18 | url:
19 | this.relativeBackOfficePath +
20 | '/backoffice/UmbracoForms/FormTree/GetNodes?id=-1&application=forms&tree=&use=main&culture=',
21 | headers: {
22 | Accept: 'application/json',
23 | 'X-UMB-XSRF-TOKEN': token.value,
24 | },
25 | }).then((response) => {
26 | const forms = JsonHelper.getBody(response);
27 | for (const form of forms) {
28 | if (form.name === id || form.key === id) {
29 | cy.deleteFormByGuid(forms.id);
30 | break;
31 | }
32 | }
33 | });
34 | });
35 | } else {
36 | // assume guid
37 | cy.deleteFormByGuid(id);
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/cypress/commands/deleteFormByGuid.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class DeleteFormByGuid extends CommandBase {
4 | commandName = 'deleteFormByGuid';
5 |
6 | method(guid) {
7 | const cy = this.cy;
8 |
9 | if (guid == null) {
10 | return;
11 | }
12 |
13 | return cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
14 | return cy
15 | .request({
16 | method: 'DELETE',
17 | url: this.relativeBackOfficePath + '/backoffice/UmbracoForms/Form/DeleteByGuid?guid=' + guid,
18 | json: true,
19 | headers: {
20 | Accept: 'application/json',
21 | 'X-UMB-XSRF-TOKEN': token.value,
22 | },
23 | })
24 | .then((resp) => {
25 | return resp;
26 | });
27 | });
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/cypress/commands/deleteFormsByNamePrefix.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class DeleteFormsByNamePrefix extends CommandBase {
5 | commandName = 'deleteFormsByNamePrefix';
6 |
7 | method(prefix) {
8 | const cy = this.cy;
9 |
10 | return cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
11 | return cy
12 | .request({
13 | method: 'GET',
14 | url:
15 | this.relativeBackOfficePath +
16 | '/backoffice/UmbracoForms/FormTree/GetNodes?id=-1&application=forms&tree=&use=main&culture=',
17 | headers: {
18 | Accept: 'application/json',
19 | 'X-UMB-XSRF-TOKEN': token.value,
20 | },
21 | })
22 | .then((response) => {
23 | const items = JsonHelper.getBody(response);
24 | for (const item of items) {
25 | if (item.name?.startsWith(prefix)) {
26 | cy.deleteFormByGuid(item.id);
27 | }
28 | }
29 | return;
30 | });
31 | });
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/cypress/commands/deletePreValueSourceByGuid.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class DeletePreValueSourceByGuid extends CommandBase {
4 | commandName = 'deletePreValueSourceByGuId';
5 |
6 | method(guid) {
7 | const cy = this.cy;
8 |
9 | if (guid == null) {
10 | return;
11 | }
12 |
13 | return cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
14 | return cy
15 | .request({
16 | method: 'DELETE',
17 | url: `${this.relativeBackOfficePath}/backoffice/UmbracoForms/PreValueSource/DeleteByGuid?guid=${guid}`,
18 | json: true,
19 | headers: {
20 | Accept: 'application/json',
21 | 'X-UMB-XSRF-TOKEN': token.value,
22 | },
23 | })
24 | .then((resp) => {
25 | return resp;
26 | });
27 | });
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/cypress/commands/deleteTemplateById.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class DeleteTemplateById extends CommandBase {
5 | commandName = 'deleteTemplateById';
6 |
7 | method(id) {
8 | const cy = this.cy;
9 | if (id == null) {
10 | return;
11 | }
12 | return cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
13 | cy.request({
14 | method: 'POST',
15 | url: this.relativeBackOfficePath + '/backoffice/UmbracoApi/Template/DeleteById?id=' + id,
16 | headers: {
17 | contentType: 'application/json',
18 | 'X-UMB-XSRF-TOKEN': token.value,
19 | },
20 | }).then((response) => {
21 | return response;
22 | });
23 | });
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/cypress/commands/deleteTemplatesByNamePrefix.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class DeleteTemplatesByNamePrefix extends CommandBase {
5 | commandName = 'deleteTemplatesByNamePrefix';
6 |
7 | method(prefix) {
8 | const cy = this.cy;
9 |
10 | return cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
11 | cy.request({
12 | method: 'GET',
13 | url:
14 | this.relativeBackOfficePath +
15 | '/backoffice/UmbracoTrees/TemplatesTree/GetNodes?id=-1&application=settings&tree=&use=main&culture=',
16 | headers: {
17 | Accept: 'application/json',
18 | 'X-UMB-XSRF-TOKEN': token.value,
19 | },
20 | }).then((response) => {
21 | const items = JsonHelper.getBody(response);
22 |
23 | for (const item of items) {
24 | if (item.name?.startsWith(prefix)) {
25 | cy.deleteTemplateById(item.id);
26 | }
27 | }
28 | return;
29 | });
30 | });
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/cypress/commands/editTemplate.ts:
--------------------------------------------------------------------------------
1 | import { JsonHelper } from '../../helpers/jsonHelper';
2 | import CommandBase from './commandBase';
3 |
4 | export default class UmbracoEditTemplate extends CommandBase {
5 | _commandName = 'editTemplate';
6 |
7 | method(name, content) {
8 | const cy = this.cy;
9 |
10 | cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
11 | // Get a list of all templates
12 | cy.request({
13 | method: 'GET',
14 | url: this._relativeBackOfficePath + '/backoffice/UmbracoTrees/TemplatesTree/GetNodes?id=-1',
15 | followRedirect: true,
16 | headers: {
17 | Accept: 'application/json',
18 | 'X-UMB-XSRF-TOKEN': token.value,
19 | },
20 | log: false,
21 | // Find template by name
22 | }).then((resonse) => {
23 | const searchBody = JsonHelper.getBody(resonse);
24 | if (searchBody.length > 0) {
25 | let templateId = null;
26 | for (const sb of searchBody) {
27 | if (sb.name === name) {
28 | templateId = sb.id;
29 | }
30 | }
31 |
32 | if (templateId !== null) {
33 | // Template found, find details of that template
34 | cy.request({
35 | method: 'GET',
36 | url: this._relativeBackOfficePath + '/backoffice/UmbracoApi/Template/GetById?id=' + templateId,
37 | followRedirect: false,
38 | headers: {
39 | Accept: 'application/json',
40 | 'X-UMB-XSRF-TOKEN': token.value,
41 | },
42 | }).then((resp) => {
43 | // Change the content and save that template
44 | const template = JsonHelper.getBody(resp);
45 | template.content = content;
46 | return cy.saveTemplate(template);
47 | });
48 | }
49 | }
50 | });
51 | });
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/cypress/commands/getAngular.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | export default class GetAngular extends CommandBase {
3 | commandName = 'getAngular';
4 | method() {
5 | return cy.window().its('angular');
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/cypress/commands/postFile.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class PostFile extends CommandBase {
5 | commandName = 'postFile';
6 | method(fileName: string, url: string) {
7 | const cy = this.cy;
8 | const method = 'POST';
9 | url = this.relativeBackOfficePath + url;
10 | const formData = new FormData();
11 |
12 | cy.fixture(fileName, 'base64').then((fileFixture) => {
13 | const blob = Cypress.Blob.base64StringToBlob(fileFixture);
14 | // @ts-ignore
15 | const testFile = new File([blob], fileName);
16 | formData.append('file', testFile);
17 | cy.getCookie('UMB-XSRF-TOKEN').then((token) => {
18 | cy.server({
19 | ignore: (request) => {
20 | return;
21 | },
22 | });
23 | cy.route(method, url).as('postAdd');
24 | cy.window()
25 | .then((win) => {
26 | const xhr = new win.XMLHttpRequest();
27 | xhr.open(method, url);
28 | xhr.setRequestHeader('X-UMB-XSRF-TOKEN', token.value);
29 | xhr.send(formData);
30 | })
31 | .wait('@postAdd')
32 | .then((res) => {
33 | return JsonHelper.getBody(res.response);
34 | });
35 | });
36 | });
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/cypress/commands/postRequest.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class PostRequest extends CommandBase {
5 | commandName = 'postRequest';
6 | method(url: string, payload: any) {
7 | const cy = this.cy;
8 | const method = 'POST';
9 | url = this.relativeBackOfficePath + url;
10 |
11 | cy.getCookie('UMB-XSRF-TOKEN').then((token) => {
12 | cy.server({
13 | ignore: (request) => {
14 | return;
15 | },
16 | });
17 | cy.route(method, url).as('postRequest');
18 | cy.window()
19 | .then((win) => {
20 | const xhr = new win.XMLHttpRequest();
21 | xhr.open(method, url);
22 | xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
23 | xhr.setRequestHeader('X-UMB-XSRF-TOKEN', token.value);
24 | xhr.send(JSON.stringify(payload));
25 | })
26 | .wait('@postRequest')
27 | .then((res) => {
28 | return JsonHelper.getBody(res.response);
29 | });
30 | });
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/cypress/commands/saveCodeFile.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class SaveCodeFile extends CommandBase {
4 | commandName = 'saveCodeFile';
5 |
6 | method(codeFile) {
7 | const cy = this.cy;
8 |
9 | if (codeFile == null) {
10 | return;
11 | }
12 |
13 | return cy.umbracoApiRequest(
14 | this.relativeBackOfficePath + '/backoffice/UmbracoApi/CodeFile/PostSave',
15 | 'POST',
16 | codeFile,
17 | );
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/cypress/commands/saveContent.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class SaveContent extends CommandBase {
5 | commandName = 'saveContent';
6 |
7 | method(content) {
8 | const cy = this.cy;
9 |
10 | if (content == null) {
11 | return;
12 | }
13 |
14 | const method = 'POST';
15 | const url = this.relativeBackOfficePath + '/backoffice/UmbracoApi/Content/PostSave';
16 | const formData = new FormData();
17 | formData.append('contentItem', JSON.stringify(content));
18 | return cy.getCookie('UMB-XSRF-TOKEN').then((token) => {
19 | cy.server({
20 | ignore: (request) => {
21 | return;
22 | },
23 | });
24 | cy.route(method, url).as('postSave');
25 | cy.window()
26 | .then((win) => {
27 | const xhr = new win.XMLHttpRequest();
28 | xhr.open(method, url);
29 | xhr.setRequestHeader('X-UMB-XSRF-TOKEN', token.value);
30 | xhr.send(formData);
31 | })
32 | .wait('@postSave')
33 | .then((res) => {
34 | return JsonHelper.getBody(res.response);
35 | });
36 | });
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/cypress/commands/saveDataType.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class SaveDataType extends CommandBase {
4 | commandName = 'saveDataType';
5 |
6 | method(dataType) {
7 | const cy = this.cy;
8 |
9 | if (dataType == null) {
10 | return;
11 | }
12 |
13 | return cy.umbracoApiRequest(
14 | this.relativeBackOfficePath + '/backoffice/UmbracoApi/DataType/PostSave',
15 | 'POST',
16 | dataType,
17 | );
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/cypress/commands/saveDocumentType.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class SaveDocumentType extends CommandBase {
4 | commandName = 'saveDocumentType';
5 |
6 | method(docType) {
7 | const cy = this.cy;
8 |
9 | if (docType == null) {
10 | return;
11 | }
12 |
13 | return cy.umbracoApiRequest(
14 | this.relativeBackOfficePath + '/backoffice/UmbracoApi/ContentType/PostSave',
15 | 'POST',
16 | docType,
17 | );
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/cypress/commands/saveFolder.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class SaveFolder extends CommandBase {
5 | commandName = 'saveFolder';
6 |
7 | method(section, name) {
8 | const cy = this.cy;
9 |
10 | if (section == null) {
11 | return;
12 | }
13 |
14 | return cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
15 | cy.request({
16 | method: 'POST',
17 | url:
18 | this.relativeBackOfficePath +
19 | '/backoffice/UmbracoApi/CodeFile/PostCreateContainer?type=' +
20 | section +
21 | '&parentId=-1&name=' +
22 | name,
23 | timeout: 90000,
24 | headers: {
25 | Accept: 'application/json, text/plain, */*',
26 | 'X-UMB-XSRF-TOKEN': token.value,
27 | },
28 | }).then((response) => {
29 | return JsonHelper.getBody(response);
30 | });
31 | });
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/cypress/commands/saveForm.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class SaveForm extends CommandBase {
4 | commandName = 'saveForm';
5 |
6 | method(form) {
7 | const cy = this.cy;
8 |
9 | if (form == null) {
10 | return;
11 | }
12 |
13 | return cy.umbracoApiRequest(this.relativeBackOfficePath + '/backoffice/UmbracoForms/Form/SaveForm', 'POST', form);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/cypress/commands/saveMacro.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class SaveMacro extends CommandBase {
4 | commandName = 'saveMacro';
5 |
6 | method(name: string) {
7 | const cy = this.cy;
8 | if (name.length == 0) {
9 | return;
10 | }
11 |
12 | return cy.umbracoApiRequest(
13 | this.relativeBackOfficePath + '/backoffice/UmbracoApi/Macros/Create?name=' + name,
14 | 'POST',
15 | );
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/cypress/commands/saveMedia.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from "./commandBase";
2 | import {JsonHelper} from "../../helpers/jsonHelper";
3 |
4 | export default class SaveMedia extends CommandBase {
5 | commandName = 'saveMedia';
6 |
7 | method(media, file) {
8 | const cy = this.cy;
9 |
10 | if (media == null) {
11 | return;
12 | }
13 |
14 | const method = 'POST';
15 | const url = this.relativeBackOfficePath + '/backoffice/UmbracoApi/Media/PostSave';
16 | const formData = new FormData();
17 | formData.append('contentItem', JSON.stringify(media));
18 |
19 | if (file != null) {
20 | formData.append('file_umbracoFile__', file)
21 | }
22 |
23 | return cy.getCookie('UMB-XSRF-TOKEN').then((token) => {
24 | cy.server({
25 | ignore: (request) => {
26 | return;
27 | },
28 | });
29 | cy.route(method, url).as('postSave');
30 | cy.window()
31 | .then((win) => {
32 | const xhr = new win.XMLHttpRequest();
33 | xhr.open(method, url);
34 | xhr.setRequestHeader('X-UMB-XSRF-TOKEN', token.value);
35 | xhr.send(formData);
36 | })
37 | .wait('@postSave')
38 | .then((res) => {
39 | return JsonHelper.getBody(res.response);
40 | });
41 | });
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/cypress/commands/savePartialView.ts:
--------------------------------------------------------------------------------
1 | import SaveCodeFile from './saveCodeFile';
2 |
3 | export default class SavePartialView extends SaveCodeFile {
4 | commandName = 'savePartialView';
5 | }
6 |
--------------------------------------------------------------------------------
/src/cypress/commands/savePartialViewMacro.ts:
--------------------------------------------------------------------------------
1 | import SaveCodeFile from './saveCodeFile';
2 |
3 | export default class SavePartialViewMacro extends SaveCodeFile {
4 | commandName = 'savePartialViewMacro';
5 | }
6 |
--------------------------------------------------------------------------------
/src/cypress/commands/saveScript.ts:
--------------------------------------------------------------------------------
1 | import SaveCodeFile from './saveCodeFile';
2 |
3 | export default class SaveScript extends SaveCodeFile {
4 | commandName = 'saveScript';
5 | }
6 |
--------------------------------------------------------------------------------
/src/cypress/commands/saveStylesheet.ts:
--------------------------------------------------------------------------------
1 | import SaveCodeFile from './saveCodeFile';
2 |
3 | export default class SaveStylesheet extends SaveCodeFile {
4 | commandName = 'saveStylesheet';
5 | }
6 |
--------------------------------------------------------------------------------
/src/cypress/commands/saveTemplate.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class SaveTemplate extends CommandBase {
4 | commandName = 'saveTemplate';
5 |
6 | method(template) {
7 | const cy = this.cy;
8 |
9 | if (template == null) {
10 | return;
11 | }
12 |
13 | return cy.umbracoApiRequest(
14 | this.relativeBackOfficePath + '/backoffice/UmbracoApi/Template/PostSave',
15 | 'POST',
16 | template,
17 | );
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/cypress/commands/saveUser.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class SaveUser extends CommandBase {
4 | commandName = 'saveUser';
5 |
6 | method(user) {
7 | const cy = this.cy;
8 |
9 | if (user == null) {
10 | return;
11 | }
12 |
13 | return cy.umbracoApiRequest(
14 | this.relativeBackOfficePath + '/backoffice/umbracoapi/users/PostCreateUser',
15 | 'POST',
16 | user,
17 | );
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/cypress/commands/saveUserGroup.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class SaveUserGroup extends CommandBase {
4 | commandName = 'saveUserGroup';
5 |
6 | method(userGroup) {
7 | const cy = this.cy;
8 |
9 | if (userGroup == null) {
10 | return;
11 | }
12 |
13 | return cy.umbracoApiRequest(
14 | this.relativeBackOfficePath + '/backoffice/umbracoapi/usergroups/PostSaveUserGroup',
15 | 'POST',
16 | userGroup,
17 | );
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoApiRequest.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class UmbracoApiRequest extends CommandBase {
5 | commandName = 'umbracoApiRequest';
6 |
7 | method(url, method, body) {
8 | const cy = this.cy;
9 |
10 | if (url == null || url === '') {
11 | return null;
12 | }
13 |
14 | return cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
15 | cy.request({
16 | method: method ?? 'GET',
17 | url: url,
18 | body: body,
19 | timeout: 90000,
20 | json: true,
21 | headers: {
22 | Accept: 'application/json',
23 | 'X-UMB-XSRF-TOKEN': token.value,
24 | },
25 | }).then((response) => {
26 | if (response.isOkStatusCode && response.body != null) {
27 | return JsonHelper.getBody(response);
28 | }
29 | return null;
30 | });
31 | });
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoButtonByLabelKey.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class UmbracoButtonByLabelKey extends CommandBase {
4 | _commandName = 'umbracoButtonByLabelKey';
5 |
6 | method(label) {
7 | const cy = this.cy;
8 | const cypress = this.cypress;
9 |
10 | cypress.log({
11 | displayName: 'Umbraco Button',
12 | });
13 |
14 | return cy.get('umb-button[label-key="' + label + '"] button:enabled', {
15 | log: false,
16 | });
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoContextMenuAction.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class UmbracoContextMenuAction extends CommandBase {
4 | _commandName = 'umbracoContextMenuAction';
5 |
6 | method(actionName) {
7 | const cy = this.cy;
8 | const cypress = this.cypress;
9 |
10 | cypress.log({
11 | displayName: 'Umbraco Context Menu Action',
12 | message: actionName,
13 | });
14 |
15 | return cy.get('li.umb-action[data-element="' + actionName + '"]', {
16 | log: false,
17 | });
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoCreateDocTypeWithContent.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { DocumentTypeBuilder } from '../../cms/builders/documentTypes/documentTypeBuilder';
3 | import { ContentBuilder } from '../../cms/builders/content/contentBuilder';
4 | export default class UmbracoCreateDocTypeWithContent extends CommandBase {
5 | _commandName = 'umbracoCreateDocTypeWithContent';
6 |
7 | method(name, alias, dataTypeBuilder) {
8 | cy.saveDataType(dataTypeBuilder).then((dataType) => {
9 | // Create a document type using the data type
10 | const docType = new DocumentTypeBuilder()
11 | .withName(name)
12 | .withAlias(alias)
13 | .withAllowAsRoot(true)
14 | .withDefaultTemplate(alias)
15 | .addGroup()
16 | .addCustomProperty(dataType['id'])
17 | .withAlias('umbracoTest')
18 | .done()
19 | .done()
20 | .build();
21 |
22 | cy.saveDocumentType(docType).then((generatedDocType) => {
23 | const contentNode = new ContentBuilder()
24 | .withContentTypeAlias(generatedDocType['alias'])
25 | .addVariant()
26 | .withName(name)
27 | .withSave(true)
28 | .done()
29 | .build();
30 |
31 | cy.saveContent(contentNode);
32 | });
33 | });
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoEditorHeaderName.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { AliasHelper } from '../../helpers/aliasHelper';
3 |
4 | export default class UmbracoEditorHeaderName extends CommandBase {
5 | _commandName = 'umbracoEditorHeaderName';
6 |
7 | method(typedText) {
8 | const cy = this.cy;
9 | const cypress = this.cypress;
10 |
11 | cypress.log({
12 | displayName: 'Umbraco Editor Header Name',
13 | });
14 |
15 | cy.get('#headerName', { log: false }).type(typedText, { timeout: 10000 }).should('have.value', typedText);
16 |
17 | cy.get('.umb-editor-header__name-wrapper').then(($wrapper) => {
18 | if ($wrapper.find('[name="lockedFieldForm"]').length > 0) {
19 | const alias = AliasHelper.toAlias(typedText);
20 | cy.get('input[name="lockedField"]').should('have.value', alias);
21 | }
22 | });
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoEnsureDataTypeNameNotExists.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class UmbracoEnsureDataTypeNameNotExists extends CommandBase {
5 | _commandName = 'umbracoEnsureDataTypeNameNotExists';
6 |
7 | method(name) {
8 | const cy = this.cy;
9 |
10 | cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
11 | cy.request({
12 | method: 'GET',
13 | url: this._relativeBackOfficePath + '/backoffice/UmbracoApi/DataType/GetByName?name=' + name,
14 | followRedirect: true,
15 | headers: {
16 | Accept: 'application/json',
17 | 'X-UMB-XSRF-TOKEN': token.value,
18 | },
19 | log: false,
20 | }).then((response) => {
21 | const searchBody = JsonHelper.getBody(response);
22 | if (searchBody != null) {
23 | const dataTypeId = searchBody.id;
24 |
25 | if (dataTypeId !== null) {
26 | cy.request({
27 | method: 'POST',
28 | url: this._relativeBackOfficePath + '/backoffice/UmbracoApi/DataType/DeleteById?id=' + dataTypeId,
29 | followRedirect: false,
30 | headers: {
31 | ContentType: 'application/json',
32 | 'X-UMB-XSRF-TOKEN': token.value,
33 | },
34 | }).then((resp) => {
35 | return;
36 | });
37 | }
38 | }
39 | });
40 | });
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoEnsureDocumentTypeNameNotExists.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class UmbracoEnsureDocumentTypeNameNotExists extends CommandBase {
5 | _commandName = 'umbracoEnsureDocumentTypeNameNotExists';
6 |
7 | method(name) {
8 | const cy = this.cy;
9 |
10 | cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
11 | cy.request({
12 | method: 'GET',
13 | url: this._relativeBackOfficePath + '/backoffice/UmbracoTrees/ContentTypeTree/GetNodes?id=-1',
14 | followRedirect: true,
15 | headers: {
16 | Accept: 'application/json',
17 | 'X-UMB-XSRF-TOKEN': token.value,
18 | },
19 | log: false,
20 | }).then((response) => {
21 | const searchBody = JsonHelper.getBody(response);
22 | if (searchBody.length > 0) {
23 | let documentTypeId = null;
24 | for (const sb of searchBody) {
25 | if (sb.name === name) {
26 | documentTypeId = sb.id;
27 | }
28 | }
29 |
30 | if (documentTypeId !== null) {
31 | cy.request({
32 | method: 'POST',
33 | url: this._relativeBackOfficePath + '/backoffice/UmbracoApi/ContentType/DeleteById?id=' + documentTypeId,
34 | followRedirect: false,
35 | headers: {
36 | ContentType: 'application/json',
37 | 'X-UMB-XSRF-TOKEN': token.value,
38 | },
39 | }).then((resp) => {
40 | return;
41 | });
42 | }
43 | }
44 | });
45 | });
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoEnsureLanguageNameNotExists.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class UmbracoEnsureLanguageNameNotExists extends CommandBase {
5 | _commandName = 'umbracoEnsureLanguageNameNotExists';
6 |
7 | method(name) {
8 | const cy = this.cy;
9 |
10 | cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
11 | cy.request({
12 | method: 'GET',
13 | url: this._relativeBackOfficePath + '/backoffice/UmbracoApi/Language/GetAllLanguages',
14 | followRedirect: true,
15 | headers: {
16 | Accept: 'application/json',
17 | 'X-UMB-XSRF-TOKEN': token.value,
18 | },
19 | log: false,
20 | }).then((response) => {
21 | const searchBody = JsonHelper.getBody(response);
22 | if (searchBody.length > 0) {
23 | let languageId = null;
24 | for (const sb of searchBody) {
25 | if (sb.name === name) {
26 | languageId = sb.id;
27 | }
28 | }
29 |
30 | if (languageId !== null) {
31 | cy.request({
32 | method: 'POST',
33 | url: this._relativeBackOfficePath + '/backoffice/UmbracoApi/Language/DeleteLanguage?id=' + languageId,
34 | followRedirect: false,
35 | headers: {
36 | ContentType: 'application/json',
37 | 'X-UMB-XSRF-TOKEN': token.value,
38 | },
39 | }).then((resp) => {
40 | return;
41 | });
42 | }
43 | }
44 | });
45 | });
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoEnsureMacroNameNotExists.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class UmbracoEnsureMacroNameNotExists extends CommandBase {
5 | _commandName = 'umbracoEnsureMacroNameNotExists';
6 |
7 | method(name) {
8 | const cy = this.cy;
9 |
10 | cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
11 | cy.request({
12 | method: 'GET',
13 | url: this._relativeBackOfficePath + '/backoffice/UmbracoTrees/MacrosTree/GetNodes?id=-1',
14 | followRedirect: true,
15 | headers: {
16 | Accept: 'application/json',
17 | 'X-UMB-XSRF-TOKEN': token.value,
18 | },
19 | log: false,
20 | }).then((response) => {
21 | const searchBody = JsonHelper.getBody(response);
22 | if (searchBody.length > 0) {
23 | let macroId = null;
24 | for (const sb of searchBody) {
25 | if (sb.name === name) {
26 | macroId = sb.id;
27 | }
28 | }
29 |
30 | if (macroId !== null) {
31 | cy.request({
32 | method: 'POST',
33 | url: this._relativeBackOfficePath + '/backoffice/UmbracoApi/Macros/DeleteById?id=' + macroId,
34 | followRedirect: false,
35 | headers: {
36 | ContentType: 'application/json',
37 | 'X-UMB-XSRF-TOKEN': token.value,
38 | },
39 | }).then((resp) => {
40 | return;
41 | });
42 | }
43 | }
44 | });
45 | });
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoEnsureMediaTypeNameNotExists.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class UmbracoEnsureMediaTypeNameNotExists extends CommandBase {
5 | _commandName = 'umbracoEnsureMediaTypeNameNotExists';
6 |
7 | method(name) {
8 | const cy = this.cy;
9 |
10 | cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
11 | cy.request({
12 | method: 'GET',
13 | url: this._relativeBackOfficePath + '/backoffice/UmbracoTrees/MediaTypeTree/GetNodes?id=-1',
14 | followRedirect: true,
15 | headers: {
16 | Accept: 'application/json',
17 | 'X-UMB-XSRF-TOKEN': token.value,
18 | },
19 | log: false,
20 | }).then((response) => {
21 | const searchBody = JsonHelper.getBody(response);
22 | if (searchBody.length > 0) {
23 | let mediaTypeId = null;
24 | for (const sb of searchBody) {
25 | if (sb.name === name) {
26 | mediaTypeId = sb.id;
27 | }
28 | }
29 |
30 | if (mediaTypeId !== null) {
31 | cy.request({
32 | method: 'POST',
33 | url: this._relativeBackOfficePath + '/backoffice/UmbracoApi/MediaType/DeleteById?id=' + mediaTypeId,
34 | followRedirect: false,
35 | headers: {
36 | ContentType: 'application/json',
37 | 'X-UMB-XSRF-TOKEN': token.value,
38 | },
39 | }).then((resp) => {
40 | return;
41 | });
42 | }
43 | }
44 | });
45 | });
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoEnsureMemberEmailNotExists.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class UmbracoEnsureMemberEmailNotExists extends CommandBase {
5 | _commandName = 'umbracoEnsureMemberEmailNotExists';
6 |
7 | method(email) {
8 | const cy = this.cy;
9 |
10 | cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
11 | cy.request({
12 | method: 'GET',
13 | url:
14 | this._relativeBackOfficePath +
15 | '/backoffice/UmbracoApi/Member/GetPagedResults?pageNumber=1&pageSize=1&orderBy=Name&orderDirection=Ascending&filter=' +
16 | email,
17 | followRedirect: true,
18 | headers: {
19 | Accept: 'application/json',
20 | 'X-UMB-XSRF-TOKEN': token.value,
21 | },
22 | log: false,
23 | }).then((response) => {
24 | const searchBody = JsonHelper.getBody(response);
25 | if (searchBody.totalItems >= 1) {
26 | const memberKey = searchBody.items[0].key;
27 | cy.request({
28 | method: 'POST',
29 | url: this._relativeBackOfficePath + '/backoffice/UmbracoApi/Member/DeleteByKey?key=' + memberKey,
30 | followRedirect: false,
31 | headers: {
32 | ContentType: 'application/json',
33 | 'X-UMB-XSRF-TOKEN': token.value,
34 | },
35 | }).then((resp) => {
36 | return;
37 | });
38 | }
39 | });
40 | });
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoEnsureMemberGroupNameNotExists.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class UmbracoEnsureMemberGroupNameNotExists extends CommandBase {
5 | _commandName = 'umbracoEnsureMemberGroupNameNotExists';
6 |
7 | method(name) {
8 | const cy = this.cy;
9 |
10 | cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
11 | cy.request({
12 | method: 'GET',
13 | url: this._relativeBackOfficePath + '/backoffice/UmbracoTrees/MemberGroupTree/GetNodes?id=-1',
14 | followRedirect: true,
15 | headers: {
16 | Accept: 'application/json',
17 | 'X-UMB-XSRF-TOKEN': token.value,
18 | },
19 | log: false,
20 | }).then((response) => {
21 | const searchBody = JsonHelper.getBody(response);
22 | if (searchBody.length > 0) {
23 | let memberGroupId = null;
24 | for (const sb of searchBody) {
25 | if (sb.name === name) {
26 | memberGroupId = sb.id;
27 | }
28 | }
29 |
30 | if (memberGroupId !== null) {
31 | cy.request({
32 | method: 'POST',
33 | url: this._relativeBackOfficePath + '/backoffice/UmbracoApi/MemberGroup/DeleteById?id=' + memberGroupId,
34 | followRedirect: false,
35 | headers: {
36 | ContentType: 'application/json',
37 | 'X-UMB-XSRF-TOKEN': token.value,
38 | },
39 | }).then((resp) => {
40 | return;
41 | });
42 | }
43 | }
44 | });
45 | });
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoEnsureMemberTypeNameNotExists.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class UmbracoEnsureMemberTypeNameNotExists extends CommandBase {
5 | _commandName = 'umbracoEnsureMemberTypeNameNotExists';
6 |
7 | method(name) {
8 | const cy = this.cy;
9 |
10 | cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
11 | cy.request({
12 | method: 'GET',
13 | url: this._relativeBackOfficePath + '/backoffice/UmbracoApi/MemberType/GetAllTypes',
14 | followRedirect: true,
15 | headers: {
16 | Accept: 'application/json',
17 | 'X-UMB-XSRF-TOKEN': token.value,
18 | },
19 | log: false,
20 | }).then((response) => {
21 | const searchBody = JsonHelper.getBody(response);
22 | if (searchBody.length > 0) {
23 | let memberTypeId = null;
24 | for (const sb of searchBody) {
25 | if (sb.name === name) {
26 | memberTypeId = sb.id;
27 | }
28 | }
29 |
30 | if (memberTypeId !== null) {
31 | cy.request({
32 | method: 'POST',
33 | url: this._relativeBackOfficePath + '/backoffice/UmbracoApi/MemberType/DeleteById?id=' + memberTypeId,
34 | followRedirect: false,
35 | headers: {
36 | ContentType: 'application/json',
37 | 'X-UMB-XSRF-TOKEN': token.value,
38 | },
39 | }).then((resp) => {
40 | return;
41 | });
42 | }
43 | }
44 | });
45 | });
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoEnsureMultipleDocumentTypeNameNotExists.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class UmbracoEnsureMultipleDocumentTypeNameNotExists extends CommandBase {
4 | _commandName = 'umbracoEnsureMultipleDocumentTypeNameNotExists';
5 | method(names) {
6 | names.forEach(function (value) {
7 | cy.umbracoEnsureDocumentTypeNameNotExists(value);
8 | });
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoEnsurePackageNameNotExists.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class UmbracoEnsurePackageNameNotExists extends CommandBase {
5 | _commandName = 'umbracoEnsurePackageNameNotExists';
6 |
7 | method(name) {
8 | const cy = this.cy;
9 | const relativeBackOfficePath = this._relativeBackOfficePath;
10 | cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
11 | cy.request({
12 | method: 'GET',
13 | url: relativeBackOfficePath + '/backoffice/umbracoapi/package/GetCreatedPackages',
14 | followRedirect: true,
15 | headers: {
16 | Accept: 'application/json',
17 | 'X-UMB-XSRF-TOKEN': token.value,
18 | },
19 | log: false,
20 | }).then((response) => {
21 | const searchBody = JsonHelper.getBody(response);
22 | if (searchBody.length > 0) {
23 | searchBody.forEach(function (value){
24 | if(name == value.name){
25 | cy.request({
26 | method: 'POST',
27 | url:
28 | relativeBackOfficePath + '/backoffice/umbracoapi/package/DeleteCreatedPackage?packageId=' + value.id,
29 | followRedirect: false,
30 | headers: {
31 | ContentType: 'application/json',
32 | 'X-UMB-XSRF-TOKEN': token.value,
33 | },
34 | });
35 | }
36 | });
37 | }
38 | });
39 | });
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoEnsurePartialViewMacroFileNameNotExists.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class UmbracoEnsurePartialViewMacroFileNameNotExists extends CommandBase {
5 | _commandName = 'umbracoEnsurePartialViewMacroFileNameNotExists';
6 |
7 | method(name) {
8 | const cy = this.cy;
9 |
10 | cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
11 | cy.request({
12 | method: 'GET',
13 | url: this._relativeBackOfficePath + '/backoffice/UmbracoTrees/PartialViewMacrosTree/GetNodes?id=-1',
14 | followRedirect: true,
15 | headers: {
16 | Accept: 'application/json',
17 | 'X-UMB-XSRF-TOKEN': token.value,
18 | },
19 | log: false,
20 | }).then((response) => {
21 | const searchBody = JsonHelper.getBody(response);
22 | if (searchBody.length > 0) {
23 | let partialViewId = null;
24 | for (const sb of searchBody) {
25 | if (sb.name === name) {
26 | partialViewId = sb.id;
27 | }
28 | }
29 |
30 | if (partialViewId !== null) {
31 | cy.request({
32 | method: 'POST',
33 | url:
34 | this._relativeBackOfficePath +
35 | '/backoffice/UmbracoApi/CodeFile/Delete?type=partialViewMacros&virtualPath=' +
36 | partialViewId,
37 | followRedirect: false,
38 | headers: {
39 | ContentType: 'application/json',
40 | 'X-UMB-XSRF-TOKEN': token.value,
41 | },
42 | }).then((resp) => {
43 | return;
44 | });
45 | }
46 | }
47 | });
48 | });
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoEnsurePartialViewNameNotExists.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class UmbracoEnsurePartialViewNameNotExists extends CommandBase {
5 | _commandName = 'umbracoEnsurePartialViewNameNotExists';
6 |
7 | method(name) {
8 | const cy = this.cy;
9 |
10 | cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
11 | cy.request({
12 | method: 'GET',
13 | url: this._relativeBackOfficePath + '/backoffice/UmbracoTrees/PartialViewsTree/GetNodes?id=-1',
14 | followRedirect: true,
15 | headers: {
16 | Accept: 'application/json',
17 | 'X-UMB-XSRF-TOKEN': token.value,
18 | },
19 | log: false,
20 | }).then((response) => {
21 | const searchBody = JsonHelper.getBody(response);
22 | if (searchBody.length > 0) {
23 | let partialViewId = null;
24 | for (const sb of searchBody) {
25 | if (sb.name === name) {
26 | partialViewId = sb.id;
27 | }
28 | }
29 |
30 | if (partialViewId !== null) {
31 | cy.request({
32 | method: 'POST',
33 | url:
34 | this._relativeBackOfficePath +
35 | '/backoffice/UmbracoApi/CodeFile/Delete?type=partialViews&virtualPath=' +
36 | partialViewId,
37 | followRedirect: false,
38 | headers: {
39 | ContentType: 'application/json',
40 | 'X-UMB-XSRF-TOKEN': token.value,
41 | },
42 | }).then((resp) => {
43 | return;
44 | });
45 | }
46 | }
47 | });
48 | });
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoEnsureRelationTypeNameNotExists.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class UmbracoEnsureRelationTypeNameNotExists extends CommandBase {
5 | _commandName = 'umbracoEnsureRelationTypeNameNotExists';
6 |
7 | method(name) {
8 | const cy = this.cy;
9 |
10 | cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
11 | cy.request({
12 | method: 'GET',
13 | url: this._relativeBackOfficePath + '/backoffice/UmbracoTrees/RelationTypeTree/GetNodes?id=-1',
14 | followRedirect: true,
15 | headers: {
16 | Accept: 'application/json',
17 | 'X-UMB-XSRF-TOKEN': token.value,
18 | },
19 | log: false,
20 | }).then((response) => {
21 | const searchBody = JsonHelper.getBody(response);
22 | if (searchBody.length > 0) {
23 | let relationTypeId = null;
24 | for (const sb of searchBody) {
25 | if (sb.name === name) {
26 | relationTypeId = sb.id;
27 | }
28 | }
29 |
30 | if (relationTypeId !== null) {
31 | cy.request({
32 | method: 'POST',
33 | url: this._relativeBackOfficePath + '/backoffice/UmbracoApi/RelationType/DeleteById?id=' + relationTypeId,
34 | followRedirect: false,
35 | headers: {
36 | ContentType: 'application/json',
37 | 'X-UMB-XSRF-TOKEN': token.value,
38 | },
39 | }).then((resp) => {
40 | return;
41 | });
42 | }
43 | }
44 | });
45 | });
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoEnsureScriptNameNotExists.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class UmbracoEnsureScriptNameNotExists extends CommandBase {
5 | _commandName = 'umbracoEnsureScriptNameNotExists';
6 |
7 | method(name) {
8 | const cy = this.cy;
9 |
10 | cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
11 | cy.request({
12 | method: 'GET',
13 | url: this._relativeBackOfficePath + '/BackOffice/Api/ScriptsTree/GetNodes?id=-1',
14 | followRedirect: true,
15 | headers: {
16 | Accept: 'application/json',
17 | 'X-UMB-XSRF-TOKEN': token.value,
18 | },
19 | log: false,
20 | }).then((response) => {
21 | const searchBody = JsonHelper.getBody(response);
22 | if (searchBody.length > 0) {
23 | let partialViewId = null;
24 | for (const sb of searchBody) {
25 | if (sb.name === name) {
26 | partialViewId = sb.id;
27 | }
28 | }
29 |
30 | if (partialViewId !== null) {
31 | cy.request({
32 | method: 'POST',
33 | url:
34 | this._relativeBackOfficePath +
35 | '/backoffice/UmbracoApi/CodeFile/Delete?type=scripts&virtualPath=' +
36 | partialViewId,
37 | followRedirect: false,
38 | headers: {
39 | ContentType: 'application/json',
40 | 'X-UMB-XSRF-TOKEN': token.value,
41 | },
42 | }).then((resp) => {
43 | return;
44 | });
45 | }
46 | }
47 | });
48 | });
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoEnsureStylesheetNameNotExists.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class UmbracoEnsureStylesheetNameNotExists extends CommandBase {
5 | _commandName = 'umbracoEnsureStylesheetNameNotExists';
6 |
7 | method(name) {
8 | const cy = this.cy;
9 |
10 | cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
11 | cy.request({
12 | method: 'GET',
13 | url: this._relativeBackOfficePath + '/BackOffice/Api/StylesheetsTree/GetNodes?id=-1',
14 | followRedirect: true,
15 | headers: {
16 | Accept: 'application/json',
17 | 'X-UMB-XSRF-TOKEN': token.value,
18 | },
19 | log: false,
20 | }).then((response) => {
21 | const searchBody = JsonHelper.getBody(response);
22 | if (searchBody.length > 0) {
23 | let partialViewId = null;
24 | for (const sb of searchBody) {
25 | if (sb.name === name) {
26 | partialViewId = sb.id;
27 | }
28 | }
29 |
30 | if (partialViewId !== null) {
31 | cy.request({
32 | method: 'POST',
33 | url:
34 | this._relativeBackOfficePath +
35 | '/backoffice/UmbracoApi/CodeFile/Delete?type=stylesheets&virtualPath=' +
36 | partialViewId,
37 | followRedirect: false,
38 | headers: {
39 | ContentType: 'application/json',
40 | 'X-UMB-XSRF-TOKEN': token.value,
41 | },
42 | }).then((resp) => {
43 | return;
44 | });
45 | }
46 | }
47 | });
48 | });
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoEnsureTemplateNameNotExists.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class UmbracoEnsureTemplateNameNotExists extends CommandBase {
5 | _commandName = 'umbracoEnsureTemplateNameNotExists';
6 |
7 | method(name) {
8 | const cy = this.cy;
9 |
10 | cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
11 | cy.request({
12 | method: 'GET',
13 | url: this._relativeBackOfficePath + '/backoffice/UmbracoTrees/TemplatesTree/GetNodes?id=-1',
14 | followRedirect: true,
15 | headers: {
16 | Accept: 'application/json',
17 | 'X-UMB-XSRF-TOKEN': token.value,
18 | },
19 | log: false,
20 | }).then((response) => {
21 | const searchBody = JsonHelper.getBody(response);
22 | if (searchBody.length > 0) {
23 | let templateId = null;
24 | for (const sb of searchBody) {
25 | if (sb.name === name) {
26 | templateId = sb.id;
27 | }
28 | }
29 |
30 | if (templateId !== null) {
31 | cy.request({
32 | method: 'POST',
33 | url: this._relativeBackOfficePath + '/backoffice/UmbracoApi/Template/DeleteById?id=' + templateId,
34 | followRedirect: false,
35 | headers: {
36 | ContentType: 'application/json',
37 | 'X-UMB-XSRF-TOKEN': token.value,
38 | },
39 | }).then((resp) => {
40 | return;
41 | });
42 | }
43 | }
44 | });
45 | });
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoEnsureUserEmailNotExists.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class UmbracoEnsureUserEmailNotExists extends CommandBase {
5 | _commandName = 'umbracoEnsureUserEmailNotExists';
6 |
7 | method(email) {
8 | const cy = this.cy;
9 |
10 | cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
11 | cy.request({
12 | method: 'GET',
13 | url:
14 | this._relativeBackOfficePath +
15 | '/backoffice/UmbracoApi/Users/GetPagedUsers?pageNumber=1&pageSize=1&orderBy=Name&orderDirection=Ascending&filter=' +
16 | email,
17 | followRedirect: true,
18 | headers: {
19 | Accept: 'application/json',
20 | 'X-UMB-XSRF-TOKEN': token.value,
21 | },
22 | log: false,
23 | }).then((response) => {
24 | const searchBody = JsonHelper.getBody(response);
25 | if (searchBody.totalItems >= 1) {
26 | const userId = searchBody.items[0].id;
27 | cy.request({
28 | method: 'POST',
29 | url: this._relativeBackOfficePath + '/backoffice/UmbracoApi/Users/PostDeleteNonLoggedInUser?id=' + userId,
30 | followRedirect: false,
31 | headers: {
32 | ContentType: 'application/json',
33 | 'X-UMB-XSRF-TOKEN': token.value,
34 | },
35 | }).then((resp) => {
36 | return;
37 | });
38 | }
39 | });
40 | });
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoEnsureUserGroupNameNotExists.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | export default class UmbracoEnsureUserGroupNameNotExists extends CommandBase {
5 | _commandName = 'umbracoEnsureUserGroupNameNotExists';
6 |
7 | method(name) {
8 | const cy = this.cy;
9 |
10 | cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
11 | cy.request({
12 | method: 'GET',
13 | url:
14 | this._relativeBackOfficePath + '/backoffice/UmbracoApi/UserGroups/GetUserGroups?onlyCurrentUserGroups=false',
15 | followRedirect: true,
16 | headers: {
17 | Accept: 'application/json',
18 | 'X-UMB-XSRF-TOKEN': token.value,
19 | },
20 | log: false,
21 | }).then((response) => {
22 | const searchBody = JsonHelper.getBody(response);
23 | if (searchBody.length > 0) {
24 | let userGroupId = null;
25 | for (const sb of searchBody) {
26 | if (sb.name === name) {
27 | userGroupId = sb.id;
28 | }
29 | }
30 |
31 | if (userGroupId !== null) {
32 | cy.request({
33 | method: 'POST',
34 | url:
35 | this._relativeBackOfficePath +
36 | '/backoffice/UmbracoApi/UserGroups/PostDeleteUserGroups?userGroupIds=' +
37 | userGroupId,
38 | followRedirect: false,
39 | headers: {
40 | ContentType: 'application/json',
41 | 'X-UMB-XSRF-TOKEN': token.value,
42 | },
43 | }).then((resp) => {
44 | return;
45 | });
46 | }
47 | }
48 | });
49 | });
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoErrorNotification.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class UmbracoErrorNotification extends CommandBase {
4 | _commandName = 'umbracoErrorNotification';
5 |
6 | method() {
7 | const cy = this.cy;
8 |
9 | cy.get('.umb-notifications__notifications > .alert-error', {
10 | log: false,
11 | timout: 60000, // This is often tested after a long running operation
12 | });
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoFileExists.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class UmbracoFileExists extends CommandBase {
4 | _commandName = 'umbracoFileExists';
5 | _endPoint;
6 |
7 | method(name) {
8 | const cy = this.cy;
9 |
10 | cy.umbracoApiRequest(this._relativeBackOfficePath + this._endPoint).then((searchBody) => {
11 | if (searchBody.length > 0) {
12 | for (const sb of searchBody) {
13 | if (sb.name === name) {
14 | return true;
15 | }
16 | }
17 | }
18 | return false;
19 | });
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoGlobalHelp.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class UmbracoGlobalHelp extends CommandBase {
4 | commandName = 'umbracoGlobalHelp';
5 |
6 | method() {
7 | const cy = this.cy;
8 |
9 | return cy.get('[data-element="global-help"]');
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoGlobalUser.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class UmbracoGlobalUser extends CommandBase {
4 | commandName = 'umbracoGlobalUser';
5 |
6 | method() {
7 | const cy = this.cy;
8 |
9 | return cy.get('[data-element="global-user"]');
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoInstall.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import faker from 'faker';
3 |
4 | export default class UmbracoInstall extends CommandBase {
5 | _commandName = 'umbracoInstall';
6 |
7 | method(
8 | username: string = Cypress.env('username'),
9 | password: string = Cypress.env('password'),
10 | connectionString: string = Cypress.env('connectionString'),
11 | ): void {
12 | const cy = this.cy;
13 | return cy.visit(`/install`, { failOnStatusCode: false }).then(() => {
14 | cy.server();
15 | cy.route('GET', '/install/api/GetSetup').as('getSetup');
16 | cy.route('POST', '/install/api/PostValidateDatabaseConnection').as('validateDatabase');
17 | cy.route('GET', '/install/api/GetPackages').as('getPackages');
18 | cy.wait('@getSetup').then(() => {
19 | cy.get('input[placeholder="Full name"').type(faker.random.word());
20 | cy.get('input[placeholder="you@example.com"').type(username);
21 | cy.get('input[name="installer.current.model.password"').type(password);
22 | cy.get('.control-customize').click();
23 |
24 | cy.get('#dbType').select('Custom connection string');
25 | cy.get('.input-block-level').type(connectionString);
26 | cy.get('form').submit();
27 | cy.wait('@validateDatabase').then(() => {
28 | cy.wait('@getPackages').then(() => {
29 | cy.get('.btn-link-reverse').click();
30 | cy.waitUntil(() => cy.getCookie('UMB-XSRF-TOKEN'), { timeout: 2400000, interval: 500 }).then((p) => {
31 | this.cy.log('Umbraco installed');
32 | return;
33 | });
34 | });
35 | });
36 | });
37 | });
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoMacroExists.ts:
--------------------------------------------------------------------------------
1 | import UmbracoFileExists from './umbracoFileExists';
2 |
3 | export default class UmbracoMacroExists extends UmbracoFileExists {
4 | _commandName = 'umbracoMacroExists';
5 | _endPoint = '/backoffice/UmbracoTrees/MacrosTree/GetNodes?id=-1';
6 | }
7 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoPartialViewExists.ts:
--------------------------------------------------------------------------------
1 | import UmbracoFileExists from './umbracoFileExists';
2 |
3 | export default class UmbracoPartialViewExists extends UmbracoFileExists {
4 | _commandName = 'umbracoPartialViewExists';
5 | _endPoint = '/backoffice/UmbracoTrees/PartialViewsTree/GetNodes?id=-1';
6 | }
7 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoRefreshContentTree.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class UmbracoRefreshContentTree extends CommandBase {
4 | _commandName = 'umbracoRefreshContentTree';
5 | method (){
6 | // Refresh to update the tree
7 | cy.get('li .umb-tree-root:contains("Content")').should("be.visible").rightclick();
8 | cy.umbracoContextMenuAction("action-refreshNode").click();
9 | // We have to wait in case the execution is slow, otherwise we'll try and click the item before it appears in the UI
10 | cy.get('.umb-tree-item__inner').should('exist', {timeout: 10000});
11 | }
12 | }
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoScriptExists.ts:
--------------------------------------------------------------------------------
1 | import UmbracoFileExists from './umbracoFileExists';
2 |
3 | export default class UmbracoScriptExists extends UmbracoFileExists {
4 | _commandName = 'umbracoScriptExists';
5 | _endPoint = '/BackOffice/Api/ScriptsTree/GetNodes?id=-1';
6 | }
7 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoSection.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class UmbracoSection extends CommandBase {
4 | _commandName = 'umbracoSection';
5 |
6 | method(sectionAlias) {
7 | const cy = this.cy;
8 | const cypress = this.cypress;
9 |
10 | cy.get('[data-element="section-' + sectionAlias + '"]', {
11 | log: false,
12 | }).click({ log: false });
13 |
14 | cypress.log({
15 | displayName: 'Umbraco Section ',
16 | });
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoSetCurrentUserLanguage.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 | import { JsonHelper } from '../../helpers/jsonHelper';
3 |
4 | /**
5 | * This will set the currently logged in Users language
6 | *
7 | * @param language The iso code for the language you want
8 | * @returns The JSON data in the body of the response as an object
9 | */
10 | export default class UmbracoSetCurrentUserLanguage extends CommandBase {
11 | _commandName = 'umbracoSetCurrentUserLanguage';
12 |
13 | method(language) {
14 | const cy = this.cy;
15 | cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
16 | cy.request({
17 | method: 'GET',
18 | url:
19 | this._relativeBackOfficePath +
20 | '/backoffice/umbracoapi/authentication/GetCurrentUser',
21 | followRedirect: true,
22 | headers: {
23 | Accept: 'application/json',
24 | 'X-UMB-XSRF-TOKEN': token.value,
25 | },
26 | log: false,
27 | }).then((response) => {
28 | const searchBody = JsonHelper.getBody(response);
29 | return cy.umbracoApiRequest(
30 | this.relativeBackOfficePath + '/backoffice/umbracoapi/users/PostSaveUser',
31 | 'POST',
32 | {
33 | id: searchBody.id,
34 | parentId: -1,
35 | name: searchBody.name,
36 | username: searchBody.email,
37 | culture: language,
38 | email: searchBody.email,
39 | startContentIds: [],
40 | startMediaIds: [],
41 | userGroups: searchBody.userGroups
42 | });
43 | });
44 | });
45 | }
46 | }
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoStylesheetExists.ts:
--------------------------------------------------------------------------------
1 | import UmbracoFileExists from './umbracoFileExists';
2 |
3 | export default class UmbracoStyleSheetExists extends UmbracoFileExists {
4 | _commandName = 'umbracoStylesheetExists';
5 | _endPoint = '/BackOffice/Api/StylesheetsTree/GetNodes?id=-1';
6 | }
7 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoSuccessNotification.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class UmbracoSuccessNotification extends CommandBase {
4 | _commandName = 'umbracoSuccessNotification';
5 |
6 | method() {
7 | const cy = this.cy;
8 | const cypress = this.cypress;
9 |
10 | cy.get('.umb-notifications__notifications > .alert-success', {
11 | log: false,
12 | timeout: 60000, // This is often tested after a long running operation
13 | });
14 |
15 | cypress.log({
16 | displayName: 'Umbraco Notification Success ',
17 | });
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoTreeItem.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class UmbracoTreeItem extends CommandBase {
4 | _commandName = 'umbracoTreeItem';
5 |
6 | method(treeName, itemNamePathArray) {
7 | const cy = this.cy;
8 | const cypress = this.cypress;
9 |
10 | cy.get('li > .umb-tree-root a[href*=' + treeName + ']', {
11 | log: false,
12 | }).then(($root) => {
13 | return this.findItem($root.closest('li'), itemNamePathArray, 0);
14 | });
15 |
16 | cypress.log({
17 | displayName: 'Umbraco Tree Item',
18 | message: treeName + ': ' + itemNamePathArray.join(' -> '),
19 | });
20 | }
21 |
22 | findItem(parentElement, items, index) {
23 | const itemName = items[index];
24 |
25 | const menuItems = parentElement.find('li');
26 |
27 | let foundItem = null;
28 | for (const mi of menuItems) {
29 | const menuItem = cy.$$(mi);
30 | let breakLoop = false;
31 | // @ts-ignore
32 | const xx = menuItem.find('.umb-tree-item__label').text((index, text) => {
33 | if (text === itemName) {
34 | foundItem = menuItem;
35 | breakLoop = true;
36 | }
37 | });
38 | if (breakLoop) {
39 | break;
40 | }
41 | }
42 |
43 | if (items.length === index + 1) {
44 | return foundItem;
45 | } else if (foundItem != null) {
46 | const li = foundItem.closest('li');
47 |
48 | const ul = li.find('ul').first();
49 |
50 | if (ul.hasClass('collapsed')) {
51 | li.find('[data-element="tree-item-expand"]').click();
52 | }
53 |
54 | return cy
55 | .wrap(ul)
56 | .should('not.have.class', 'collapsed')
57 | .then((xx) => {
58 | return this.findItem(ul, items, index + 1);
59 | });
60 | } else {
61 | return null;
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoVerifyRenderedViewContent.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class UmbracoVerifyRenderedViewContent extends CommandBase {
4 | _commandName = 'umbracoVerifyRenderedViewContent';
5 |
6 | method(endpoint, expectedContent, removeWhitespace = false) {
7 | const cy = this.cy;
8 |
9 | cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
10 | cy.request({
11 | method: 'GET',
12 | url: endpoint,
13 | followRedirect: true,
14 | headers: {
15 | Accept: 'text/html',
16 | 'X-UMB-XSRF-TOKEN': token.value,
17 | },
18 | log: false,
19 | }).then((response) => {
20 | let body = response.body;
21 | if (removeWhitespace) {
22 | expectedContent = expectedContent.replace(/\s/g, '');
23 | body = body.replace(/\s/g, '');
24 | }
25 | if (body === expectedContent) return true;
26 | return false;
27 | });
28 | });
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoVerifyScriptContent.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class UmbracoVerifyScriptContent extends CommandBase {
4 | _commandName = 'umbracoVerifyScriptContent';
5 |
6 | method(fileName, expectedContent) {
7 | const cy = this.cy;
8 |
9 | cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
10 | cy.request({
11 | method: 'GET',
12 | url: '/scripts/' + fileName,
13 | followRedirect: true,
14 | headers: {
15 | Accept: 'application/javascript',
16 | 'X-UMB-XSRF-TOKEN': token.value,
17 | },
18 | log: false,
19 | }).then((response) => {
20 | if (response.body === expectedContent) return true;
21 | return false;
22 | });
23 | });
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/cypress/commands/umbracoVerifyStylesheetContent.ts:
--------------------------------------------------------------------------------
1 | import CommandBase from './commandBase';
2 |
3 | export default class UmbracoVerifyStylesheetContent extends CommandBase {
4 | _commandName = 'umbracoVerifyStylesheetContent';
5 |
6 | method(fileName, expectedContent) {
7 | const cy = this.cy;
8 |
9 | cy.getCookie('UMB-XSRF-TOKEN', { log: false }).then((token) => {
10 | cy.request({
11 | method: 'GET',
12 | url: '/css/' + fileName,
13 | followRedirect: true,
14 | headers: {
15 | Accept: 'text/css',
16 | 'X-UMB-XSRF-TOKEN': token.value,
17 | },
18 | log: false,
19 | }).then((response) => {
20 | if (response.body === expectedContent) return true;
21 | return false;
22 | });
23 | });
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/forms/builders/fields/conditions/formFieldConditionBuilder.ts:
--------------------------------------------------------------------------------
1 | import { FormFieldConditionRuleBuilder } from './formFieldConditionRuleBuilder';
2 |
3 | export class FormFieldConditionBuilder {
4 | parentBuilder;
5 |
6 | actionType;
7 | enabled;
8 | logicType;
9 |
10 | formFieldConditionRuleBuilders;
11 |
12 | constructor(parentBuilder) {
13 | this.parentBuilder = parentBuilder;
14 | this.formFieldConditionRuleBuilders = [];
15 | }
16 |
17 | withActionAndLogic(actionType, logicType) {
18 | this.actionType = actionType;
19 | this.logicType = logicType;
20 | this.enabled = true;
21 | }
22 |
23 | done() {
24 | return this.parentBuilder;
25 | }
26 |
27 | addRule() {
28 | const builder = new FormFieldConditionRuleBuilder(this);
29 |
30 | this.formFieldConditionRuleBuilders.push(builder);
31 |
32 | return builder;
33 | }
34 |
35 | build() {
36 | if (!this.enabled) {
37 | return {};
38 | }
39 |
40 | return {
41 | enabled: this.enabled || false,
42 | actionType: this.actionType || '',
43 | logicType: this.logicType || null,
44 | rules: this.formFieldConditionRuleBuilders.map((builder) => {
45 | return builder.build();
46 | }),
47 | };
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/forms/builders/fields/conditions/formFieldConditionRuleBuilder.ts:
--------------------------------------------------------------------------------
1 | export class FormFieldConditionRuleBuilder {
2 | parentBuilder;
3 |
4 | field;
5 | operator;
6 | value;
7 |
8 | constructor(parentBuilder) {
9 | this.parentBuilder = parentBuilder;
10 | }
11 |
12 | withContainsRule(fieldId, value) {
13 | this.field = fieldId;
14 | this.value = value;
15 | this.operator = 'Contains';
16 |
17 | return this;
18 | }
19 |
20 | withIsRule(fieldId, value) {
21 | this.field = fieldId;
22 | this.value = value;
23 | this.operator = 'Is';
24 |
25 | return this;
26 | }
27 |
28 | withIsNotRule(fieldId, value) {
29 | this.field = fieldId;
30 | this.value = value;
31 | this.operator = 'IsNot';
32 |
33 | return this;
34 | }
35 |
36 | withGreaterThanRule(fieldId, value) {
37 | this.field = fieldId;
38 | this.value = value;
39 | this.operator = 'GreaterThen';
40 |
41 | return this;
42 | }
43 |
44 | withLessThanRule(fieldId, value) {
45 | this.field = fieldId;
46 | this.value = value;
47 | this.operator = 'LessThen';
48 |
49 | return this;
50 | }
51 |
52 | withStartsWithRule(fieldId, value) {
53 | this.field = fieldId;
54 | this.value = value;
55 | this.operator = 'StartsWith';
56 |
57 | return this;
58 | }
59 |
60 | withEndsWithRule(fieldId, value) {
61 | this.field = fieldId;
62 | this.value = value;
63 | this.operator = 'EndsWith';
64 |
65 | return this;
66 | }
67 |
68 | done() {
69 | return this.parentBuilder;
70 | }
71 |
72 | build() {
73 | return {
74 | field: this.field || null,
75 | operator: this.operator || null,
76 | value: this.value || null,
77 | };
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/forms/builders/fields/conditions/index.ts:
--------------------------------------------------------------------------------
1 | export { FormFieldConditionBuilder } from './formFieldConditionBuilder';
2 | export { FormFieldConditionRuleBuilder } from './formFieldConditionRuleBuilder';
3 |
--------------------------------------------------------------------------------
/src/forms/builders/fields/dropDownFieldBuilder.ts:
--------------------------------------------------------------------------------
1 | import { FormFieldBuilderBase } from './formFieldBuilderBase';
2 |
3 | export class DropDownFieldBuilder extends FormFieldBuilderBase {
4 | fieldTypeId = '0dd29d42-a6a5-11de-a2f2-222256d89593';
5 | removePrevalueEditor = true;
6 | prevalueSourceId = '';
7 | parentBuilder;
8 | formFieldBuilderBase: FormFieldBuilderBase;
9 |
10 | withPrevalueSourceId(value: string) {
11 | this.prevalueSourceId = value;
12 | return this;
13 | }
14 |
15 | withPrevalues(values: string[]) {
16 | this.preValues = values;
17 | return this;
18 | }
19 | build() {
20 | const baseBuild = super.build();
21 | // tslint:disable-next-line
22 | baseBuild['prevalueSourceId'] = this.prevalueSourceId;
23 | return baseBuild;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/forms/builders/fields/fileUploadFieldBuilder.ts:
--------------------------------------------------------------------------------
1 | import { FormFieldBuilderBase } from './formFieldBuilderBase';
2 |
3 | export class UploadFileFieldBuilder extends FormFieldBuilderBase {
4 | fieldTypeId = '84a17cf8-b711-46a6-9840-0e4a072ad000';
5 | removePrevalueEditor = true;
6 |
7 | withDefaultValue(defaultValue: string) {
8 | // tslint:disable-next-line: no-string-literal
9 | this.settings['DefaultValue'] = defaultValue;
10 | return this;
11 | }
12 |
13 | withPlaceholder(placeholder) {
14 | // tslint:disable-next-line: no-string-literal
15 | this.settings['Placeholder'] = placeholder;
16 | return this;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/forms/builders/fields/formCheckboxFieldBuilder.ts:
--------------------------------------------------------------------------------
1 | import { FormFieldBuilderBase } from './formFieldBuilderBase';
2 |
3 | export class FormCheckboxFieldBuilder extends FormFieldBuilderBase {
4 | fieldTypeId = 'd5c0c390-ae9a-11de-a69e-666455d89593';
5 | removePrevalueEditor = true;
6 |
7 | withDefaultValue(defaultValue: string) {
8 | // tslint:disable-next-line: no-string-literal
9 | this.settings['DefaultValue'] = defaultValue;
10 |
11 | return this;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/forms/builders/fields/formDateFieldBuilder.ts:
--------------------------------------------------------------------------------
1 | import { FormFieldBuilderBase } from './formFieldBuilderBase';
2 |
3 | export class FormDateFieldBuilder extends FormFieldBuilderBase {
4 | fieldTypeId = 'f8b4c3b8-af28-11de-9dd8-ef5956d89593';
5 | removePrevalueEditor = true;
6 | }
7 |
--------------------------------------------------------------------------------
/src/forms/builders/fields/formLongAnswerFieldBuilder.ts:
--------------------------------------------------------------------------------
1 | import { FormFieldBuilderBase } from './formFieldBuilderBase';
2 |
3 | export class FormLongAnswerFieldBuilder extends FormFieldBuilderBase {
4 | fieldTypeId = '023f09ac-1445-4bcb-b8fa-ab49f33bd046';
5 | removePrevalueEditor = true;
6 |
7 | withDefaultValue(defaultValue: string) {
8 | // tslint:disable-next-line: no-string-literal
9 | this.settings['DefaultValue'] = defaultValue;
10 | return this;
11 | }
12 |
13 | withPlaceholder(placeholder) {
14 | // tslint:disable-next-line: no-string-literal
15 | this.settings['Placeholder'] = placeholder;
16 | return this;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/forms/builders/fields/formPasswordFieldBuilder.ts:
--------------------------------------------------------------------------------
1 | import { FormFieldBuilderBase } from './formFieldBuilderBase';
2 |
3 | export class FormPasswordFieldBuilder extends FormFieldBuilderBase {
4 | fieldTypeId = 'fb37bc60-d41e-11de-aeae-37c155d89593';
5 | removePrevalueEditor = true;
6 |
7 | withPlaceholder(placeholder) {
8 | // tslint:disable-next-line: no-string-literal
9 | this.settings['Placeholder'] = placeholder;
10 | return this;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/forms/builders/fields/formShortAnswerFieldBuilder.ts:
--------------------------------------------------------------------------------
1 | import { FormFieldBuilderBase } from './formFieldBuilderBase';
2 |
3 | export class FormShortAnswerFieldBuilder extends FormFieldBuilderBase {
4 | fieldTypeId = '3f92e01b-29e2-4a30-bf33-9df5580ed52c';
5 | removePrevalueEditor = true;
6 |
7 | withDefaultValue(defaultValue: string) {
8 | // tslint:disable-next-line: no-string-literal
9 | this.settings['DefaultValue'] = defaultValue;
10 | return this;
11 | }
12 |
13 | withPlaceholder(placeholder) {
14 | // tslint:disable-next-line: no-string-literal
15 | this.settings['Placeholder'] = placeholder;
16 | return this;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/forms/builders/fields/index.ts:
--------------------------------------------------------------------------------
1 | export { FormCheckboxFieldBuilder } from './formCheckboxFieldBuilder';
2 | export { FormDateFieldBuilder } from './formDateFieldBuilder';
3 | export { FormFieldBuilderBase } from './formFieldBuilderBase';
4 | export { FormLongAnswerFieldBuilder } from './formLongAnswerFieldBuilder';
5 | export { FormPasswordFieldBuilder } from './formPasswordFieldBuilder';
6 | export { FormShortAnswerFieldBuilder } from './formShortAnswerFieldBuilder';
7 | export { DropDownFieldBuilder } from './dropDownFieldBuilder';
8 | export { UploadFileFieldBuilder } from './fileUploadFieldBuilder';
9 |
--------------------------------------------------------------------------------
/src/forms/builders/formFieldSetBuilder.ts:
--------------------------------------------------------------------------------
1 | import { FormContainerBuilder } from './formContainerBuilder';
2 |
3 | export class FormFieldSetBuilder {
4 | parentBuilder;
5 | caption;
6 |
7 | formContainerBuilders;
8 | withCaption(caption) {
9 | this.caption = caption;
10 | return this;
11 | }
12 |
13 | constructor(parentBuilder) {
14 | this.parentBuilder = parentBuilder;
15 | this.formContainerBuilders = [];
16 | }
17 |
18 | addContainer() {
19 | const builder = new FormContainerBuilder(this);
20 |
21 | this.formContainerBuilders.push(builder);
22 |
23 | return builder;
24 | }
25 |
26 | done() {
27 | return this.parentBuilder;
28 | }
29 |
30 | build() {
31 | return {
32 | caption: this.caption || null,
33 | containers: this.formContainerBuilders.map((builder) => {
34 | return builder.build();
35 | }),
36 | };
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/forms/builders/formPageBuilder.ts:
--------------------------------------------------------------------------------
1 | import { FormFieldSetBuilder } from './formFieldSetBuilder';
2 |
3 | export class FormPageBuilder {
4 | parentBuilder;
5 | caption;
6 |
7 | formFieldSetBuilders;
8 |
9 | withCaption(caption) {
10 | this.caption = caption;
11 |
12 | return this;
13 | }
14 |
15 | constructor(parentBuilder) {
16 | this.parentBuilder = parentBuilder;
17 | this.formFieldSetBuilders = [];
18 | }
19 |
20 | addFieldSet() {
21 | const builder = new FormFieldSetBuilder(this);
22 |
23 | this.formFieldSetBuilders.push(builder);
24 |
25 | return builder;
26 | }
27 |
28 | done() {
29 | return this.parentBuilder;
30 | }
31 |
32 | build() {
33 | return {
34 | caption: this.caption || null,
35 | fieldSets: this.formFieldSetBuilders.map((builder) => {
36 | return builder.build();
37 | }),
38 | };
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/forms/builders/helpers/contentBuilderHelper.ts:
--------------------------------------------------------------------------------
1 | import { ContentBuilder, Template, CmsDocumentType } from '../../..';
2 |
3 | export class ContentBuilderHelper {
4 | public build(templateAlias, documentTypeAlias: string, properties?: any[]) {
5 | const content = new ContentBuilder()
6 | .withTemplateAlias(templateAlias)
7 | .withContentTypeAlias(documentTypeAlias)
8 | .addVariant()
9 | .withSave(true)
10 | .withPublish(true);
11 | properties?.forEach((property) => {
12 | content.addProperty().withAlias(property.alias).withValue(property.value).done();
13 | });
14 |
15 | return content.done().build();
16 | }
17 | public buildContent_(templateBody, docTypeBody, formPickerAlias: string, formBody) {
18 | return new ContentBuilder()
19 | .withTemplateAlias(templateBody.alias)
20 | .withContentTypeAlias(docTypeBody.alias)
21 | .addVariant()
22 | .withSave(true)
23 | .withPublish(true)
24 | .addProperty()
25 | .withAlias(formPickerAlias)
26 | .withValue(formBody.id)
27 | .done()
28 | .done()
29 | .build();
30 | }
31 |
32 | public insert(template: Template, documentType: CmsDocumentType, properties) {
33 | const content = this.build(template.alias, documentType.alias, properties);
34 | return cy.saveContent(content).then((contentBody) => contentBody);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/forms/builders/helpers/dataSourcesBuilderHelper.ts:
--------------------------------------------------------------------------------
1 | export class DataSourcesBuilderHelper {
2 | private readonly dataSourceWebServiceDataSourceId = '7edf567c-4230-4079-b3fb-cca44baf6b75';
3 | private readonly dataSourceSqlDataSourceId = 'f19506f3-efea-4b13-a308-89348f69df91';
4 |
5 | public insertWebService(
6 | name: string,
7 | settings: {
8 | InsertMethod: string;
9 | Password: string;
10 | ServiceName: string;
11 | ServiceUrl: string;
12 | UserName: string;
13 | },
14 | ) {
15 | const payload = {
16 | formDataSourceTypeId: this.dataSourceWebServiceDataSourceId,
17 | name,
18 | settings,
19 | };
20 | return cy.postRequest('/backoffice/UmbracoForms/DataSource/PostSave', payload).then((postsave) => postsave);
21 | }
22 |
23 | public insertSqlDatabase(
24 | name: string,
25 | settings: {
26 | Connection: string;
27 | Table: string;
28 | },
29 | ) {
30 | const payload = {
31 | formDataSourceTypeId: this.dataSourceSqlDataSourceId,
32 | name,
33 | settings,
34 | };
35 | return cy.postRequest('/backoffice/UmbracoForms/DataSource/PostSave', payload).then((postsave) => postsave);
36 | }
37 | public cleanUp() {
38 | return cy.deleteAllDataSources();
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/forms/builders/helpers/documentTypeBuilderHelper.ts:
--------------------------------------------------------------------------------
1 | import faker from 'faker';
2 | import { DocumentTypeBuilder, CmsDocumentType, Template, DataType } from '../../..';
3 | import { PropertyBuilderHelper } from './propertyBuilderHelper';
4 |
5 | export class DocumentTypeBuilderHelper {
6 | public build(
7 | documentType: CmsDocumentType,
8 | template: Template,
9 | items: { property: any; dataType: DataType }[],
10 | ): DocumentTypeBuilder {
11 | const builder = new DocumentTypeBuilder()
12 | .withName(documentType.name)
13 | .withAlias(documentType.alias)
14 | .withId(documentType.id)
15 | .withDefaultTemplate(template.alias)
16 | .withAllowAsRoot(true);
17 |
18 | return new PropertyBuilderHelper().build(builder.addGroup(), items);
19 | }
20 |
21 | public buildContentType_(
22 | templateBody,
23 | docTypePrefix: string,
24 | docTypeAlias: string,
25 | dataTypeBody,
26 | formPickerAlias: string,
27 | ): DocumentTypeBuilder {
28 | return new DocumentTypeBuilder()
29 | .withName(docTypePrefix + faker.random.uuid())
30 | .withAlias(docTypeAlias)
31 | .withDefaultTemplate(decodeURI(templateBody))
32 | .withAllowAsRoot(true)
33 | .addGroup()
34 | .addFormPickerProperty()
35 | .withDataTypeId(dataTypeBody.id)
36 | .withAlias(formPickerAlias)
37 | .done()
38 | .done()
39 | .build();
40 | }
41 | public insert(documentTypeBuilder: DocumentTypeBuilder) {
42 | return cy.saveDocumentType(documentTypeBuilder.build()).then((documentTypeBody) => documentTypeBody);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/forms/builders/helpers/index.ts:
--------------------------------------------------------------------------------
1 | export { ContentBuilderHelper } from './contentBuilderHelper';
2 | export { DataSourcesBuilderHelper } from './dataSourcesBuilderHelper';
3 | export { DataTypesBuilderHelper } from './dataTypesBuilderHelper';
4 | export { DocumentTypeBuilderHelper } from './documentTypeBuilderHelper';
5 | export { PrevalueSourcesBuilderHelper } from './prevalueSourcesBuilderHelper';
6 | export { PropertyBuilderHelper } from './propertyBuilderHelper';
7 | export { TemplateBuilderHelper } from './templateBuilderHelper';
8 | export { FormBuilderHelper } from './formBuilderHelper';
9 |
--------------------------------------------------------------------------------
/src/forms/builders/helpers/prevalueSourcesBuilderHelper.ts:
--------------------------------------------------------------------------------
1 | export class PrevalueSourcesBuilderHelper {
2 | private readonly fieldPreValueSourceTextFileTypeId = '35c2053e-cbf7-4793-b27c-6e97b7671a2d';
3 | private readonly fieldPreValueSourceDocumentTypeId = 'de996870-c45a-11de-8a39-0800200c9a66';
4 | private readonly fieldPreValueSourceDataTypePrevalueId = 'ea773caf-fef2-491b-b5b7-6a3552b1a0e2';
5 |
6 | public insertTextFile(name: string) {
7 | return cy.postFile('prevaluesource.txt', '/backoffice/UmbracoForms/PreValueFile/PostAddFile').then((settings) => {
8 | const payload = {
9 | fieldPreValueSourceTypeId: this.fieldPreValueSourceTextFileTypeId,
10 | name,
11 | settings: { TextFile: settings.FilePath },
12 | };
13 | return this.insert(payload);
14 | });
15 | }
16 |
17 | public insertDocument(name: string, doctype: string) {
18 | const payload = {
19 | fieldPreValueSourceTypeId: this.fieldPreValueSourceDocumentTypeId,
20 | name,
21 | settings: { DocType: doctype },
22 | };
23 | return this.insert(payload);
24 | }
25 | public insertDataTypePrevalue(name: string, dataTypeId: number) {
26 | const payload = {
27 | fieldPreValueSourceTypeId: this.fieldPreValueSourceDataTypePrevalueId,
28 | name,
29 | settings: { DataTypeId: dataTypeId },
30 | };
31 | return this.insert(payload);
32 | }
33 | private insert(payload) {
34 | return cy.postRequest('/backoffice/UmbracoForms/PreValueSource/ValidateSettings', payload).then(() => {
35 | cy.postRequest('/backoffice/UmbracoForms/PreValueSource/PostSave', payload).then((postsave) => {
36 | cy.postRequest('/backoffice/UmbracoForms/PreValueSource/GetPreValues', payload).then(() => postsave);
37 | });
38 | });
39 | }
40 |
41 | public cleanUp() {
42 | return cy.deleteAllPreValues();
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/forms/builders/helpers/propertyBuilderHelper.ts:
--------------------------------------------------------------------------------
1 | import { DataType, DocumentTypeBuilder, TextBoxProperty, DropDownProperty, FormPickerProperty } from '../../..';
2 | import DocumentTypeGroupBuilder from '../../../cms/builders/documentTypes/documentTypeGroupBuilder';
3 |
4 | export class PropertyBuilderHelper {
5 | public build(
6 | documentTypeGroupBuilder: DocumentTypeGroupBuilder,
7 | items: { property: any; dataType: DataType }[],
8 | ): DocumentTypeBuilder {
9 | items?.forEach((item: { property: any; dataType: DataType }) => {
10 | let builder;
11 | if (item.property instanceof TextBoxProperty) {
12 | builder = documentTypeGroupBuilder.addTextBoxProperty();
13 | } else if (item.property instanceof DropDownProperty) {
14 | builder = documentTypeGroupBuilder.addDropDownProperty();
15 | } else if (item.property instanceof FormPickerProperty) {
16 | builder = documentTypeGroupBuilder.addFormPickerProperty();
17 | }
18 | builder.withDataTypeId(item.dataType.id).withAlias(item.property.alias).done();
19 | });
20 | return documentTypeGroupBuilder.done();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/forms/builders/iBuilder.ts:
--------------------------------------------------------------------------------
1 | export interface IBuilder {
2 | done();
3 | build();
4 | }
5 |
--------------------------------------------------------------------------------
/src/forms/builders/index.ts:
--------------------------------------------------------------------------------
1 | export { FormBuilder } from './formBuilder';
2 | export { FormContainerBuilder } from './formContainerBuilder';
3 | export { FormFieldSetBuilder } from './formFieldSetBuilder';
4 | export { FormPageBuilder } from './formPageBuilder';
5 |
--------------------------------------------------------------------------------
/src/forms/builders/workflows/index.ts:
--------------------------------------------------------------------------------
1 | export { FormWorkflowBuilder } from './formWorkflowBuilder';
2 | export { WorkflowTypeSetting } from './workflowTypeSetting';
3 |
--------------------------------------------------------------------------------
/src/forms/builders/workflows/workflowTypeSetting.ts:
--------------------------------------------------------------------------------
1 | import faker from 'faker';
2 | import { IBuilder } from '../iBuilder';
3 |
4 | export class WorkflowTypeSetting {
5 | parentBuilder: IBuilder;
6 |
7 | description: string;
8 | name: string;
9 | prevalues: string[];
10 | value: string;
11 | view: string;
12 | constructor(parentBuilder: IBuilder) {
13 | this.parentBuilder = parentBuilder;
14 | this.description = faker.lorem.words(4);
15 | this.name = '';
16 | this.prevalues = [''];
17 | this.value = '';
18 | this.view = '/App_Plugins/UmbracoForms/Backoffice/Common/SettingTypes/TextField.html';
19 | }
20 |
21 | withDescription(description: string): WorkflowTypeSetting {
22 | this.description = description;
23 | return this;
24 | }
25 |
26 | withName(name: string): WorkflowTypeSetting {
27 | this.name = name;
28 | return this;
29 | }
30 |
31 | withPrevalues(prevalues: string[]): WorkflowTypeSetting {
32 | this.prevalues = prevalues;
33 | return this;
34 | }
35 |
36 | withValue(value: string): WorkflowTypeSetting {
37 | this.value = value;
38 | return this;
39 | }
40 | withView(view: string): WorkflowTypeSetting {
41 | this.view = view;
42 | return this;
43 | }
44 |
45 | done(): IBuilder {
46 | return this.parentBuilder;
47 | }
48 |
49 | build() {
50 | return {
51 | alias: this.name,
52 | description: this.description,
53 | name: this.name,
54 | prevalues: this.prevalues,
55 | value: this.value,
56 | view: this.view,
57 | };
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/forms/models/checkboxField.ts:
--------------------------------------------------------------------------------
1 | import { FormField } from './formField';
2 |
3 | export class CheckboxField extends FormField {}
4 |
--------------------------------------------------------------------------------
/src/forms/models/dateField.ts:
--------------------------------------------------------------------------------
1 | import { FormField } from './formField';
2 |
3 | export class DateField extends FormField {}
4 |
--------------------------------------------------------------------------------
/src/forms/models/dropDownField.ts:
--------------------------------------------------------------------------------
1 | import { FormField } from './formField';
2 |
3 | export class DropDownField extends FormField {
4 | constructor(
5 | id: string,
6 | public alias?: string,
7 | public caption?: string,
8 | public value?: string,
9 | containsSensitiveData?: boolean,
10 | mandatory?: boolean,
11 | requiredErrorMessage?: string,
12 | regex?: string,
13 | public prevalueSourceId?: string,
14 | public preValues?: string[],
15 | ) {
16 | super(id, containsSensitiveData, mandatory, requiredErrorMessage, regex);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/forms/models/fileUploadField.ts:
--------------------------------------------------------------------------------
1 | import { FormField } from './formField';
2 |
3 | export class FileUploadField extends FormField {
4 | constructor(
5 | id: string,
6 | public alias?: string,
7 | public caption?: string,
8 | containsSensitiveData?: boolean,
9 | mandatory?: boolean,
10 | requiredErrorMessage?: string,
11 | regex?: string,
12 | ) {
13 | super(id, containsSensitiveData, mandatory, requiredErrorMessage, regex);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/forms/models/formField.ts:
--------------------------------------------------------------------------------
1 | export class FormField {
2 | constructor(
3 | public id: string,
4 | public containsSensitiveData: boolean = false,
5 | public mandatory: boolean = false,
6 | public requiredErrorMessage: string = '',
7 | public regex: string = '',
8 | ) {}
9 | }
10 |
--------------------------------------------------------------------------------
/src/forms/models/formModel.ts:
--------------------------------------------------------------------------------
1 | import faker from 'faker';
2 | export class FormModel {
3 | public name = faker.random.word();
4 | }
5 |
--------------------------------------------------------------------------------
/src/forms/models/index.ts:
--------------------------------------------------------------------------------
1 | export { CheckboxField } from './checkboxField';
2 | export { DateField } from './dateField';
3 | export { DropDownField } from './dropDownField';
4 | export { FileUploadField } from './fileUploadField';
5 | export { FormModel } from './formModel';
6 | export { LongAnswerField } from './longAnswerField';
7 | export { PasswordField } from './passwordField';
8 | export { SendEmailRazorModel } from './sendEmailRazorModel';
9 | export { ShortAnswerField } from './shortAnswerField';
10 | export { Workflow } from './workflow';
11 | export { WorkflowSettings } from './workflowSettings';
12 | export { SaveAsUmbracoContentNodeWorkflowModel } from './saveAsUmbracoContentNodeWorkflowModel';
13 |
--------------------------------------------------------------------------------
/src/forms/models/longAnswerField.ts:
--------------------------------------------------------------------------------
1 | import { FormField } from './formField';
2 |
3 | export class LongAnswerField extends FormField {
4 | constructor(
5 | id: string,
6 | public alias?: string,
7 | public caption?: string,
8 | public value?: string,
9 | containsSensitiveData?: boolean,
10 | mandatory?: boolean,
11 | requiredErrorMessage?: string,
12 | regex?: string,
13 | ) {
14 | super(id, containsSensitiveData, mandatory, requiredErrorMessage, regex);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/forms/models/passwordField.ts:
--------------------------------------------------------------------------------
1 | import { FormField } from './formField';
2 |
3 | export class PasswordField extends FormField {
4 | constructor(
5 | id: string,
6 | public alias?: string,
7 | public caption?: string,
8 | public value?: string,
9 | containsSensitiveData?: boolean,
10 | mandatory?: boolean,
11 | requiredErrorMessage?: string,
12 | regex?: string,
13 | ) {
14 | super(id, containsSensitiveData, mandatory, requiredErrorMessage, regex);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/forms/models/saveAsUmbracoContentNodeWorkflowModel.ts:
--------------------------------------------------------------------------------
1 | export class SaveAsUmbracoContentNodeWorkflowModel {
2 | public workflowName: string;
3 | public rootNode: number;
4 | public includeSensitiveData = false;
5 | // Need to figure out how to expose enum from package. 0=Submit, 1=Approve -> for workflows
6 | public executeOn = 0;
7 | public publish = 'True';
8 | public documentType: {
9 | doctype?: string;
10 | nameField?: string;
11 | nameStaticValue?: number;
12 | properties?: [
13 | {
14 | id: string;
15 | value: string;
16 | field: string;
17 | staticvalue: string;
18 | $$hashKey: string;
19 | },
20 | ];
21 | };
22 | constructor(workflowName?: string) {
23 | this.workflowName = workflowName;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/forms/models/sendEmailRazorModel.ts:
--------------------------------------------------------------------------------
1 | import faker from 'faker';
2 |
3 | export class SendEmailRazorModel {
4 | public workflowName: string;
5 | public includeSensitiveData = false;
6 | // Need to figure out how to expose enum from package. 0=Submit, 1=Approve -> for workflows
7 | public executeOn = 0;
8 | public email: string = faker.internet.email();
9 | public senderEmail: string = faker.internet.email();
10 | public subject: string = faker.random.word();
11 | public razorViewFilePath = 'Forms/Emails/Example-Template.cshtml';
12 | public attachment = 'True';
13 |
14 | constructor(workflowName: string) {
15 | this.workflowName = workflowName;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/forms/models/shortAnswerField.ts:
--------------------------------------------------------------------------------
1 | import { FormField } from './formField';
2 |
3 | export class ShortAnswerField extends FormField {
4 | constructor(
5 | id: string,
6 | public alias?: string,
7 | public caption?: string,
8 | public value?: string,
9 | containsSensitiveData?: boolean,
10 | mandatory?: boolean,
11 | requiredErrorMessage?: string,
12 | regex?: string,
13 | ) {
14 | super(id, containsSensitiveData, mandatory, requiredErrorMessage, regex);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/forms/models/workflow.ts:
--------------------------------------------------------------------------------
1 | import { WorkflowSettings } from './workflowSettings';
2 | export class Workflow {
3 | executeOn = 0;
4 | workflowTypeId: string;
5 | includeSensitiveData = false;
6 | name: string;
7 | workflowTypeName: string;
8 | settings: any | WorkflowSettings[] = [];
9 | }
10 |
--------------------------------------------------------------------------------
/src/forms/models/workflowSettings.ts:
--------------------------------------------------------------------------------
1 | export class WorkflowSettings {
2 | name: string;
3 | value: string;
4 | }
5 |
--------------------------------------------------------------------------------
/src/forms/workflows/changeRecordStateWorkflow.ts:
--------------------------------------------------------------------------------
1 | import { Workflow } from '../models/workflow';
2 | import faker from 'faker';
3 | export enum RecordStateAction {
4 | 'Delete Record' = 0,
5 | 'Approve Record' = 1,
6 | }
7 | export class ChangeRecordStateWorkflow {
8 | public getWorkflow(
9 | workflowName: string = faker.random.word(),
10 | includeSensitiveData = false,
11 | // Need to figure out how to expose enum from package. 0=Submit, 1=Approve -> for workflows
12 | executeOn = 0,
13 | action: RecordStateAction = RecordStateAction['Approve Record'],
14 | words: string[] = ['word'],
15 | ): Workflow {
16 | const workflow = new Workflow();
17 | workflow.workflowTypeId = '4c40a092-0cb5-481d-96a7-a02d8e7cdb2f';
18 | workflow.workflowTypeName = 'Change Record State';
19 | workflow.name = workflowName;
20 | workflow.includeSensitiveData = includeSensitiveData;
21 | workflow.executeOn = executeOn;
22 | workflow.settings.push({ name: 'Words', value: words.join(',') });
23 | workflow.settings.push({ name: 'Action', value: RecordStateAction[action] });
24 | return workflow;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/forms/workflows/index.ts:
--------------------------------------------------------------------------------
1 | export { ChangeRecordStateWorkflow } from './changeRecordStateWorkflow';
2 | export { PostAsXMLWorkflow } from './postAsXMLWorkflow';
3 | export { SaveAsAnXMLFileWorkflow } from './saveAsAnXMLFileWorkflow';
4 | export { SaveAsUmbracoContentNodeWorkflow } from './saveAsUmbracoContentNodeWorkflow';
5 | export { SendEmailRazorWorkflow } from './sendEmailRazorWorkflow';
6 | export { SendEmailWorkflow } from './sendEmailWorkflow';
7 | export { SendFormToUrl } from './sendFormToUrl';
8 | export { SendXsltTransformedEmail } from './sendXsltTransformedEmail';
9 |
--------------------------------------------------------------------------------
/src/forms/workflows/postAsXMLWorkflow.ts:
--------------------------------------------------------------------------------
1 | import { Workflow } from '../models/workflow';
2 | import faker from 'faker';
3 |
4 | export enum Method {
5 | 'POST' = 0,
6 | 'GET' = 1,
7 | 'PUT' = 2,
8 | 'DELETE' = 3,
9 | }
10 | export class PostAsXMLWorkflow {
11 | public getWorkflow(
12 | workflowName: string = faker.random.word(),
13 | includeSensitiveData = false,
14 | // Need to figure out how to expose enum from package. 0=Submit, 1=Approve -> for workflows
15 | executeOn = 0,
16 | url = '127.0.0.1',
17 | method: Method = Method.POST,
18 | xsltFile = '',
19 | user = 'user',
20 | password = 'password',
21 | headers?: [{ alias: string; value: string; staticValue: string; $$hashKey: string }],
22 | ): Workflow {
23 | const workflow = new Workflow();
24 | workflow.workflowTypeId = '470eeb3a-cb15-4b08-9fc0-a2f091583332';
25 | workflow.workflowTypeName = 'Post as XML';
26 | workflow.name = workflowName;
27 | workflow.includeSensitiveData = includeSensitiveData;
28 | workflow.executeOn = executeOn;
29 | workflow.settings.push({ name: 'Url', value: url });
30 | workflow.settings.push({ name: 'Method', value: Method[method] });
31 | workflow.settings.push({ name: 'XsltFile', value: xsltFile });
32 | workflow.settings.push({ name: 'Fields', value: headers });
33 | workflow.settings.push({ name: 'Username', value: user });
34 | workflow.settings.push({ name: 'Password', value: password });
35 | return workflow;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/forms/workflows/saveAsAnXMLFileWorkflow.ts:
--------------------------------------------------------------------------------
1 | import { Workflow } from '../models/workflow';
2 | import faker from 'faker';
3 | export class SaveAsAnXMLFileWorkflow {
4 | public getWorkflow(
5 | workflowName: string = faker.random.word(),
6 | includeSensitiveData = false,
7 | // Need to figure out how to expose enum from package. 0=Submit, 1=Approve -> for workflows
8 | executeOn = 0,
9 | path = 'c:\\tmp',
10 | extension = '.mxl',
11 | xsltFile = '',
12 | ): Workflow {
13 | const workflow = new Workflow();
14 | workflow.workflowTypeId = '9cc5854d-61a2-48f6-9f4a-8f3bdfafb521';
15 | workflow.workflowTypeName = 'Save as an XML file';
16 | workflow.name = workflowName;
17 | workflow.includeSensitiveData = includeSensitiveData;
18 | workflow.executeOn = executeOn;
19 | workflow.settings.push({ name: 'Path', value: path });
20 | workflow.settings.push({ name: 'Extension', value: extension });
21 | workflow.settings.push({ name: 'XsltFile', value: xsltFile });
22 | return workflow;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/forms/workflows/saveAsUmbracoContentNodeWorkflow.ts:
--------------------------------------------------------------------------------
1 | import { Workflow } from '../models/workflow';
2 |
3 | import { SaveAsUmbracoContentNodeWorkflowModel } from '../models/saveAsUmbracoContentNodeWorkflowModel';
4 | export class SaveAsUmbracoContentNodeWorkflow {
5 | public getWorkflow(model: SaveAsUmbracoContentNodeWorkflowModel): Workflow {
6 | const workflow = new Workflow();
7 | workflow.workflowTypeId = '89fb1e31-9f36-4e08-9d1b-af1180d340db';
8 | workflow.workflowTypeName = 'Save as Umbraco content node';
9 | workflow.name = model.workflowName;
10 | workflow.includeSensitiveData = model.includeSensitiveData;
11 | workflow.executeOn = model.executeOn;
12 | workflow.settings.push({ name: 'Fields', value: model.documentType });
13 | workflow.settings.push({ name: 'Publish', value: model.publish });
14 | workflow.settings.push({ name: 'RootNode', value: model.rootNode });
15 | return workflow;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/forms/workflows/sendEmailRazorWorkflow.ts:
--------------------------------------------------------------------------------
1 | import { Workflow } from '../models/workflow';
2 | import { SendEmailRazorModel } from '../models/sendEmailRazorModel';
3 | export class SendEmailRazorWorkflow {
4 | public getWorkflow(model: SendEmailRazorModel): Workflow {
5 | const workflow = new Workflow();
6 | workflow.workflowTypeId = '17c61629-d984-4e86-b43b-a8407b3efea9';
7 | workflow.name = model.workflowName;
8 | workflow.includeSensitiveData = model.includeSensitiveData;
9 | workflow.workflowTypeName = 'Send email with template (Razor)';
10 | workflow.executeOn = model.executeOn;
11 | workflow.settings.push({ name: 'Email', value: model.email });
12 | workflow.settings.push({ name: 'SenderEmail', value: model.senderEmail });
13 | workflow.settings.push({ name: 'Subject', value: model.subject });
14 | workflow.settings.push({ name: 'RazorViewFilePath', value: model.razorViewFilePath });
15 | workflow.settings.push({ name: 'Attachment', value: model.attachment });
16 | return workflow;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/forms/workflows/sendEmailWorkflow.ts:
--------------------------------------------------------------------------------
1 | import { Workflow } from '../models/workflow';
2 | import faker from 'faker';
3 | export class SendEmailWorkflow {
4 | public getWorkflow(
5 | workflowName: string = faker.random.word(),
6 | includeSensitiveData = false,
7 | // Need to figure out how to expose enum from package. 0=Submit, 1=Approve -> for workflows
8 | executeOn = 0,
9 | email: string = faker.internet.email(),
10 | senderEmail: string = faker.internet.email(),
11 | subject: string = faker.random.word(),
12 | message: string = faker.lorem.lines(2),
13 | attachment = 'True',
14 | ): Workflow {
15 | const workflow = new Workflow();
16 | workflow.workflowTypeId = 'e96badd7-05be-4978-b8d9-b3d733de70a5';
17 | workflow.name = workflowName;
18 | workflow.workflowTypeName = 'Send email';
19 | workflow.includeSensitiveData = includeSensitiveData;
20 | workflow.executeOn = executeOn;
21 | workflow.settings.push({ name: 'Email', value: email });
22 | workflow.settings.push({ name: 'SenderEmail', value: senderEmail });
23 | workflow.settings.push({ name: 'Subject', value: subject });
24 | workflow.settings.push({ name: 'Message', value: message });
25 | workflow.settings.push({ name: 'Attachment', value: attachment });
26 | return workflow;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/forms/workflows/sendFormToUrl.ts:
--------------------------------------------------------------------------------
1 | import { Workflow } from '../models/workflow';
2 | import faker from 'faker';
3 |
4 | export enum Method {
5 | 'POST' = 0,
6 | 'GET' = 1,
7 | 'PUT' = 2,
8 | 'DELETE' = 3,
9 | }
10 | export class SendFormToUrl {
11 | public getWorkflow(
12 | workflowName: string = faker.random.word(),
13 | includeSensitiveData = false,
14 | // Need to figure out how to expose enum from package. 0=Submit, 1=Approve -> for workflows
15 | executeOn = 0,
16 | url = '127.0.0.1',
17 | method: Method = Method.POST,
18 | user = 'user',
19 | password = 'password',
20 | fields?: [{ alias: string; value: string; staticValue: string; $$hashKey: string }],
21 | ): Workflow {
22 | const workflow = new Workflow();
23 | workflow.workflowTypeId = 'fd02c929-4e7d-4f90-b9fa-13d074a76688';
24 | workflow.workflowTypeName = 'Send form to URL';
25 | workflow.name = workflowName;
26 | workflow.includeSensitiveData = includeSensitiveData;
27 | workflow.executeOn = executeOn;
28 | workflow.settings.push({ name: 'Url', value: url });
29 | workflow.settings.push({ name: 'Method', value: Method[method] });
30 | workflow.settings.push({ name: 'Fields', value: fields });
31 | workflow.settings.push({ name: 'UserName', value: user });
32 | workflow.settings.push({ name: 'Password', value: password });
33 | return workflow;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/forms/workflows/sendXsltTransformedEmail.ts:
--------------------------------------------------------------------------------
1 | import { Workflow } from '../models/workflow';
2 | import faker from 'faker';
3 |
4 | export class SendXsltTransformedEmail {
5 | public getWorkflow(
6 | workflowName: string = faker.random.word(),
7 | includeSensitiveData = false,
8 | // Need to figure out how to expose enum from package. 0=Submit, 1=Approve -> for workflows
9 | executeOn = 0,
10 | email: string = faker.internet.email(),
11 | senderEmail: string = faker.internet.email(),
12 | subject: string = faker.random.word(),
13 | xsltFile = '',
14 | ): Workflow {
15 | const workflow = new Workflow();
16 | workflow.workflowTypeId = '616edfeb-badf-414b-89dc-d8655eb85998';
17 | workflow.workflowTypeName = 'Send xslt transformed email';
18 | workflow.name = workflowName;
19 | workflow.includeSensitiveData = includeSensitiveData;
20 | workflow.executeOn = executeOn;
21 | workflow.settings.push({ name: 'Email', value: email });
22 | workflow.settings.push({ name: 'SenderEmail', value: senderEmail });
23 | workflow.settings.push({ name: 'Subject', value: subject });
24 | workflow.settings.push({ name: 'XsltFile', value: xsltFile });
25 |
26 | return workflow;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/helpers/aliasHelper.ts:
--------------------------------------------------------------------------------
1 | import camelize from 'camelize';
2 |
3 | export class AliasHelper {
4 | /**
5 | * Uses Camelize npm library to generate a safe alias from a string
6 | * that may contain spaces and dashes etc
7 | *
8 | * @param {string} text Input string
9 | * @returns {string} A camelcased string that starts with 'a' and ends with 'a'
10 | * @see {@link https://www.npmjs.com/package/camelize}
11 | */
12 | static toSafeAlias(text: string): string {
13 | return 'a' + camelize(text) + 'a';
14 | }
15 |
16 | /**
17 | * Camel cases a string by calling the toCamelCase() method
18 | *
19 | * @param {string} text Input string
20 | * @returns {string} A camelcased string
21 | */
22 | static toAlias(text: string): string {
23 | return this.toCamelCase(text);
24 | }
25 |
26 | /**
27 | * Capatilze a string
28 | *
29 | * @param {string} text Input string
30 | * @returns {string} A capatilized string, of the first character only
31 | */
32 | static capitalize(text: string): string {
33 | if (typeof text !== 'string') return '';
34 | return text.charAt(0).toUpperCase() + text.slice(1);
35 | }
36 |
37 | /**
38 | * Convert a sentence into camelCase
39 | * `toCamelCase('My aWesome Example')` would return `myAwesomeExample`
40 | *
41 | * @param {string} sentenceCase Input string
42 | * @returns {string} A camel cased string
43 | */
44 | static toCamelCase(sentenceCase: string): string {
45 | let out = '';
46 | sentenceCase.split(' ').forEach((el, idx) => {
47 | const add = el.toLowerCase();
48 | out += idx === 0 ? add : add[0].toUpperCase() + add.slice(1);
49 | });
50 | return out;
51 | }
52 |
53 | /**
54 | * Removes dashes from UUID string
55 | *
56 | * @param {string} uuid A string representing a UUID
57 | * @returns {string} UUID without dashes
58 | */
59 | static uuidToAlias(uuid: string): string {
60 | uuid = uuid.replace(/-/g, '');
61 | return this.toAlias(uuid);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/helpers/jsonHelper.ts:
--------------------------------------------------------------------------------
1 | export class JsonHelper {
2 | /**
3 | * Expects the HTTP body response to be JSON
4 | * This will remove the `)]}',\n` if present
5 | * and return the correct JSON data as an object
6 | *
7 | * @param response The raw HTTP response from the server
8 | * @returns The JSON data in the body of the response as an object
9 | */
10 | static getBody(response) {
11 | const junk = ")]}',\n";
12 | let json = response.body;
13 |
14 | if (json.length === 0) {
15 | return null;
16 | }
17 |
18 | if (json.startsWith(junk)) {
19 | json = json.substr(junk.length);
20 | }
21 | return JSON.parse(json);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/helpers/responseHelper.ts:
--------------------------------------------------------------------------------
1 | export class ResponseHelper {
2 | /**
3 | * This strips the first 6 characters of the response body
4 | * as it assumes it will **always** contain the junk json data `)]}',\n`
5 | *
6 | * It would be better to use jsonHelper.getBody()
7 | * as it checks for its presence of the data
8 | *
9 | * @param response The raw HTTP response from the server
10 | * @returns The JSON data in the body of the response as an object
11 | * @deprecated Please use jsonHelper.getBody instead
12 | * @see jsonHelper.getBody()
13 | */
14 | static getResponseBody(response) {
15 | return JSON.parse(response.body.substr(6));
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/tests/builders/dataTypeBuilder.spec.ts:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 | import faker from 'faker'
3 | import { FormPickerDataTypeBuilder } from '../../src';
4 |
5 |
6 | describe('DataType Builders', () => {
7 | it('FormPickerDataTypeBuilder Default', () => {
8 | const actual = new FormPickerDataTypeBuilder()
9 | .build();
10 |
11 | assert.equal(actual.selectedEditor ,"UmbracoForms.FormPicker");
12 | assert.equal(actual.selectedEditor ,"UmbracoForms.FormPicker");
13 | });
14 |
15 | it('FormPickerDataTypeBuilder Custom single form', () => {
16 |
17 | const name = faker.lorem.sentence();
18 | const id = faker.random.number();
19 | const formId = faker.random.uuid();
20 |
21 | const actual = new FormPickerDataTypeBuilder()
22 | .withSaveAction()
23 | .withId(id)
24 | .withName(name)
25 | .withAllowedForm(formId)
26 | .build();
27 |
28 | assert.equal(actual.id, id);
29 | assert.equal(actual.name, name);
30 | assert.equal(actual.action, "save");
31 | assert.lengthOf(actual.getPrevalues(), 1);
32 | assert.equal(actual.getPrevalues()[0].key, "allowedForms");
33 | assert.lengthOf(actual.getPrevalues()[0].value,1);
34 | assert.equal(actual.getPrevalues()[0].value[0], formId);
35 | });
36 |
37 |
38 | it('FormPickerDataTypeBuilder Custom multi form', () => {
39 | const formId1 = faker.random.uuid();
40 | const formId2 = faker.random.uuid();
41 |
42 | const actual = new FormPickerDataTypeBuilder()
43 | .withSaveNewAction()
44 | .withAllowedForms([formId1, formId2])
45 | .build();
46 |
47 | assert.equal(actual.action, "saveNew");
48 | assert.lengthOf(actual.getPrevalues(), 1);
49 | assert.equal(actual.getPrevalues()[0].key, "allowedForms");
50 | assert.lengthOf(actual.getPrevalues()[0].value,2);
51 | assert.equal(actual.getPrevalues()[0].value[0], formId1);
52 | assert.equal(actual.getPrevalues()[0].value[1], formId2);
53 | });
54 |
55 |
56 | });
57 |
--------------------------------------------------------------------------------
/tests/builders/documentTypeBuilder.spec.ts:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 | import faker from 'faker'
3 | import { DocumentTypeBuilder } from '../../src';
4 |
5 | describe('DocumentTypeBuilder', () => {
6 | it('Default build', () => {
7 | const actual = new DocumentTypeBuilder()
8 | .build();
9 | assert(actual.alias != null, 'The alias must be set');
10 | });
11 |
12 | it('Custom build', () => {
13 | const dataTypeId = faker.random.uuid();
14 | const formPickerAlias = faker.hacker.adjective();
15 | const pickerLabel = faker.lorem.sentence();
16 |
17 | const actual = new DocumentTypeBuilder()
18 | .withAllowAsRoot(true)
19 | .addGroup()
20 | .addFormPickerProperty()
21 | .withDataTypeId(dataTypeId)
22 | .withAlias(formPickerAlias)
23 | .done()
24 | .addFormPickerProperty()
25 | .withLabel(pickerLabel)
26 | .done()
27 | .done()
28 | .build();
29 |
30 | assert(actual.alias != null, 'The alias must be set');
31 | });
32 |
33 | });
34 |
--------------------------------------------------------------------------------
/tests/cypress/commands/commandBase.spec.ts:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 | import faker from "faker";
3 | import td from 'testdouble'
4 | import cypressTestDouble, {addMock} from "../testDoubles/cypressTestDouble";
5 | import cyTestDouble from "../testDoubles/cyTestDouble";
6 | import CommandBase from '../../../src/cypress/commands/commandBase';
7 |
8 |
9 |
10 | describe('CommandBase', () => {
11 | const sut = new CommandBase( "/umbraco", cyTestDouble, cypressTestDouble);
12 |
13 | it('register command must call the method', () => {
14 | const commandName = faker.name.findName();
15 | let captor = td.matchers.captor();
16 |
17 | // ensure we call the method of the class self, and therefore expect the same error
18 | td.when(addMock(commandName, captor.capture())).thenDo(() => captor.value());
19 |
20 | sut.commandName = commandName;
21 |
22 | assert.throws(() => sut.registerCommand(), Error, /You have to implement the method()/);
23 |
24 | });
25 |
26 | it('method must throw error on base class (alternative to abstract)', () => {
27 | assert.throws(() => sut.method(0,0,0,0,0,0,0), Error, /You have to implement the method()/);
28 | });
29 | });
30 |
--------------------------------------------------------------------------------
/tests/cypress/commands/umbracoLogin.spec.ts:
--------------------------------------------------------------------------------
1 | import { assert } from 'chai';
2 |
3 | describe('UmbracoLogin', () => {
4 | it('Not implemented', () =>{
5 | assert(true);
6 | });
7 | });
8 | // import { assert } from 'chai';
9 | // import UmbracoLogin from "../../../src/cypress/commands/umbracoLogin";
10 | // import faker from "faker";
11 | // import td from 'testdouble'
12 | // import cypressTestDouble from "../testDoubles/cypressTestDouble";
13 | // import cyTestDouble, {clearCookiesMock, clearLocalStorageMock, hasClassMock} from "../testDoubles/cyTestDouble";
14 | //
15 | // describe('UmbracoLogin', () => {
16 | // const sut = new UmbracoLogin( "/umbraco", cyTestDouble, cypressTestDouble);
17 | //
18 | // it('Happy path - Success, visit backoffice with tour', () => {
19 | // //Arrage
20 | // let captor = td.matchers.captor();
21 | // let username = faker.name.findName();
22 | // let password = faker.name.findName();
23 | //
24 | // //Mock
25 | // td.when(cypressTestDouble.Commands.add("umbracoLogin", captor.capture())).thenDo(() => captor.value(username, password));
26 | // td.when(hasClassMock('umb-tour-is-visible')).thenReturn(false);
27 | //
28 | // //Act
29 | // sut.method(username, password);
30 | //
31 | // //Assert
32 | //
33 | // //Verify
34 | // td.verify(clearCookiesMock());
35 | // td.verify(clearLocalStorageMock());
36 | // td.verify(hasClassMock('umb-tour-is-visible'));
37 | // });
38 | // });
39 |
--------------------------------------------------------------------------------
/tests/cypress/testDoubles/cyTestDouble.ts:
--------------------------------------------------------------------------------
1 | import td from 'testdouble'
2 |
3 | export const clearCookiesMock = td.func('cy.clearCookies');
4 | export const clearLocalStorageMock = td.func('cy.clearLocalStorageMock');
5 | export const logMock = td.func('cy.log');
6 | export const hasClassMock = td.func('cy.get(...).should(...).hasClass');
7 | export const typeMock = td.func('cy.get(...).type');
8 |
9 | export default {
10 | clearCookies: () => clearCookiesMock(),
11 | clearLocalStorage: () => clearLocalStorageMock(),
12 | log: () => logMock(),
13 |
14 | visit: (fn1) => {
15 | return {
16 | then: (fn) => fn(),
17 | }
18 | },
19 |
20 | get: (fn1) => {
21 | return {
22 | should: (s) => s({
23 | hasClass: (a) => hasClassMock(a),
24 | }),
25 | click: (fn1) => {
26 | return {
27 | then: (fn) => fn(),
28 | }
29 | },
30 | type: (text) => typeMock(text)
31 |
32 | }
33 | },
34 |
35 | request: (fn1) => {
36 | let responseBody = ')]}\',\n{"test":"json"}';
37 | return {
38 |
39 |
40 | then: (fn) => fn({body:responseBody}),
41 | }
42 | },
43 |
44 | getCookie: (fn1) => {
45 | return {
46 |
47 | then: (fn) => fn({token:"test"}),
48 | }
49 | },
50 | };
51 |
--------------------------------------------------------------------------------
/tests/cypress/testDoubles/cypressTestDouble.ts:
--------------------------------------------------------------------------------
1 | import td from 'testdouble'
2 |
3 | export const addMock = td.func('Cypress.Commands.add');
4 | export default {
5 | Commands: {
6 | add: (name, func) => addMock(name, func)
7 | }
8 | };
9 |
--------------------------------------------------------------------------------
/tests/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "types": [
4 | "jest"
5 | ],
6 | "include": [
7 | "**/*.ts"
8 | ]
9 |
10 | }
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "outDir": "./lib",
6 | "sourceMap": false,
7 | "declaration": true,
8 | "declarationDir": "./lib/types",
9 | "module": "CommonJS",
10 | "moduleResolution": "node",
11 | "emitDecoratorMetadata": true,
12 | "experimentalDecorators": true,
13 | "esModuleInterop": true,
14 | "importHelpers": true,
15 | "target": "es6",
16 | "inlineSourceMap": true,
17 | "types": [
18 | "cypress",
19 | "node"
20 | ],
21 | "lib": [
22 | "es5",
23 | "dom"
24 | ],
25 | "plugins": [
26 | {
27 | "name": "typescript-tslint-plugin",
28 | "alwaysShowRuleFailuresAsWarnings": false,
29 | "ignoreDefinitionFiles": true,
30 | "configFile": "tslint.json",
31 | "suppressWhileTypeErrorsPresent": false
32 | }
33 | ]
34 | },
35 | "include": [
36 | "src/**/*.ts"
37 | ],
38 | }
39 |
--------------------------------------------------------------------------------