Merge branch 'v8/dev' into v8/contrib
This commit is contained in:
@@ -1,34 +1,36 @@
|
||||
# Umbraco Acceptance Tests
|
||||
|
||||
### Prerequisites
|
||||
- NodeJS 12+
|
||||
- A running installed Umbraco on url: [https://localhost:44331](https://localhost:44331) (Default development port)
|
||||
- Install using a `SqlServer`/`LocalDb` as the tests execute too fast for `SqlCE` to handle.
|
||||
- User information in `cypress.env.json` (See [Getting started](#getting-started))
|
||||
|
||||
### Getting started
|
||||
The tests are located in the project/folder as `Umbraco.Tests.AcceptanceTests`. Make sure you run `npm install` in that folder, or let your IDE do that.
|
||||
|
||||
Next, it is important that you create a new file in the root of the project called `cypress.env.json`.
|
||||
This file is already added to `.gitignore` and can contain values that are different for each developer machine.
|
||||
|
||||
The file needs the following content:
|
||||
```
|
||||
{
|
||||
"username": "<email for superadmin>",
|
||||
"password": "<password for superadmin>"
|
||||
}
|
||||
```
|
||||
Replace the `<email for superadmin>` and `<password for superadmin>` placeholders with correct info.
|
||||
|
||||
|
||||
|
||||
### Executing tests
|
||||
There are two npm scripts that can be used to execute the test:
|
||||
|
||||
1. `npm run test`
|
||||
- Executes the tests headless.
|
||||
1. `npm run ui`
|
||||
- Executes the tests in a browser handled by a cypress application.
|
||||
|
||||
In case of errors it is recommended to use the UI to debug.
|
||||
# Umbraco Acceptance Tests
|
||||
|
||||
### Prerequisites
|
||||
- NodeJS 12+
|
||||
- A running installed Umbraco on url: [https://localhost:44331](https://localhost:44331) (Default development port)
|
||||
- Install using a `SqlServer`/`LocalDb` as the tests execute too fast for `SqlCE` to handle.
|
||||
|
||||
### Getting started
|
||||
The tests are located in the project/folder as `Umbraco.Tests.AcceptanceTests`. Make sure you run `npm install` in that folder, or let your IDE do that.
|
||||
|
||||
The script will ask you to enter the username and password for a superadmin user of your Umbraco CMS.
|
||||
|
||||
### Executing tests
|
||||
There are two npm scripts that can be used to execute the test:
|
||||
|
||||
1. `npm run test`
|
||||
- Executes the tests headless.
|
||||
1. `npm run ui`
|
||||
- Executes the tests in a browser handled by a cypress application.
|
||||
|
||||
In case of errors it is recommended to use the UI to debug.
|
||||
|
||||
### Enviroment Configuration
|
||||
|
||||
The enviroment configuration is begin setup by the npm installation script.
|
||||
This results in the creation of this file: `cypress.env.json`.
|
||||
This file is already added to `.gitignore` and can contain values that are different for each developer machine.
|
||||
|
||||
The file has the following content:
|
||||
```
|
||||
{
|
||||
"username": "<email for superadmin>",
|
||||
"password": "<password for superadmin>"
|
||||
}
|
||||
```
|
||||
You can change this if you like or run the config script to reset the values, type "npm run config" in your terminal.
|
||||
|
||||
49
src/Umbraco.Tests.AcceptanceTest/config.js
Normal file
49
src/Umbraco.Tests.AcceptanceTest/config.js
Normal file
@@ -0,0 +1,49 @@
|
||||
const prompt = require('prompt');
|
||||
const fs = require('fs');
|
||||
|
||||
const properties = [
|
||||
{
|
||||
description: 'Enter your superadmin username/email',
|
||||
name: 'username',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
description: 'Enter your superadmin password',
|
||||
name: 'password',
|
||||
hidden: true,
|
||||
required: true
|
||||
},
|
||||
{
|
||||
description: 'Enter CMS URL, or leave empty for default(https://localhost:44331)',
|
||||
name: 'baseUrl'
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
const configPath = './cypress.env.json'
|
||||
|
||||
console.log("Configure your test enviroment")
|
||||
|
||||
prompt.start();
|
||||
|
||||
prompt.get(properties, function (error, result) {
|
||||
if (error) { return onError(error); }
|
||||
|
||||
var fileContent = `{
|
||||
"username": "${result.username}",
|
||||
"password": "${result.password}"${
|
||||
result.baseUrl && `,
|
||||
"baseUrl": "${result.baseUrl}"`
|
||||
}
|
||||
}`;
|
||||
|
||||
fs.writeFile(configPath, fileContent, function (error) {
|
||||
if (error) return console.error(error);
|
||||
console.log('Configuration saved');
|
||||
});
|
||||
});
|
||||
|
||||
function onError(error) {
|
||||
console.error(error);
|
||||
return true;
|
||||
}
|
||||
@@ -18,4 +18,11 @@
|
||||
module.exports = (on, config) => {
|
||||
// `on` is used to hook into various events Cypress emits
|
||||
// `config` is the resolved Cypress config
|
||||
const baseUrl = config.env.baseUrl || null;
|
||||
|
||||
if (baseUrl) {
|
||||
config.baseUrl = baseUrl;
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
{
|
||||
"scripts": {
|
||||
"postinstall": "node postinstall.js",
|
||||
"config": "node config.js",
|
||||
"test": "npx cypress run",
|
||||
"ui": "npx cypress open"
|
||||
},
|
||||
@@ -7,7 +9,8 @@
|
||||
"cross-env": "^7.0.2",
|
||||
"cypress": "^5.1.0",
|
||||
"ncp": "^2.0.0",
|
||||
"umbraco-cypress-testhelpers": "^1.0.0-beta-50"
|
||||
"umbraco-cypress-testhelpers": "^1.0.0-beta-50",
|
||||
"prompt": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"typescript": "^3.9.2"
|
||||
|
||||
14
src/Umbraco.Tests.AcceptanceTest/postinstall.js
Normal file
14
src/Umbraco.Tests.AcceptanceTest/postinstall.js
Normal file
@@ -0,0 +1,14 @@
|
||||
const fs = require('fs');
|
||||
|
||||
const configPath = './cypress.env.json';
|
||||
|
||||
try {
|
||||
if (fs.existsSync(configPath)) {
|
||||
//file exists
|
||||
console.log("Skips configuration as file already exists, run 'npm run config' to change your configuration.");
|
||||
} else {
|
||||
require('./config.js');
|
||||
}
|
||||
} catch(err) {
|
||||
console.error(err)
|
||||
}
|
||||
@@ -252,7 +252,7 @@ function iconHelper($http, $q, $sce, $timeout, umbRequestHelper) {
|
||||
|
||||
/** LEGACY - Return a list of icons from icon fonts, optionally filter them */
|
||||
/** It fetches them directly from the active stylesheets in the browser */
|
||||
getLegacyIcons: function(){
|
||||
getIcons: function(){
|
||||
var deferred = $q.defer();
|
||||
$timeout(function(){
|
||||
if(collectedIcons){
|
||||
@@ -284,13 +284,8 @@ function iconHelper($http, $q, $sce, $timeout, umbRequestHelper) {
|
||||
s = s.substring(0, hasPseudo);
|
||||
}
|
||||
|
||||
var icon = {
|
||||
name: s,
|
||||
svgString: undefined
|
||||
};
|
||||
|
||||
if(collectedIcons.indexOf(icon) < 0 && s !== "icon-chevron-up" && s !== "icon-chevron-down"){
|
||||
collectedIcons.push(icon);
|
||||
if(collectedIcons.indexOf(s) < 0){
|
||||
collectedIcons.push(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
margin: 0 auto;
|
||||
cursor: pointer;
|
||||
border-radius: @baseBorderRadius;
|
||||
color: black;
|
||||
color: @ui-action-discreet-type;
|
||||
position: relative;
|
||||
opacity: 0.8;
|
||||
transition: opacity .3s ease-out;
|
||||
transition: opacity 120ms, color 120ms;
|
||||
|
||||
&--absolute {
|
||||
position: absolute;
|
||||
@@ -23,6 +23,10 @@
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: @ui-action-discreet-type-hover;
|
||||
}
|
||||
|
||||
.umb-button-ellipsis--tab,
|
||||
.umb-tour-is-visible .umb-tree &,
|
||||
&:hover,
|
||||
@@ -47,6 +51,7 @@
|
||||
&__icon {
|
||||
color: inherit;
|
||||
flex-basis: 100%;
|
||||
font-size: 12px;
|
||||
|
||||
.umb-button-ellipsis--tab & {
|
||||
margin: 0 0 7px;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
.umb-tree-root {
|
||||
.umb-tree-root {
|
||||
|
||||
border: 2px solid transparent;
|
||||
|
||||
&-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -95,7 +95,6 @@ body.touch .umb-tree {
|
||||
position: relative;
|
||||
width: auto;
|
||||
height: auto;
|
||||
margin: 0 5px 0 auto;
|
||||
overflow: visible;
|
||||
clip: auto;
|
||||
}
|
||||
@@ -185,9 +184,10 @@ body.touch .umb-tree {
|
||||
flex: 0 0 auto;
|
||||
justify-content: flex-end;
|
||||
text-align: center;
|
||||
margin: 0 5px 0 auto;
|
||||
margin: 0 10px 0 auto;
|
||||
cursor: pointer;
|
||||
border-radius: @baseBorderRadius;
|
||||
transition: background-color 120ms;
|
||||
|
||||
.umb-button-ellipsis {
|
||||
padding: 3px 5px;
|
||||
@@ -207,7 +207,7 @@ body.touch .umb-tree {
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: rgba(255, 255, 255, .5);
|
||||
background-color: rgba(255, 255, 255, .8);
|
||||
|
||||
i {
|
||||
background: @ui-active-type-hover;
|
||||
|
||||
@@ -1,4 +1,27 @@
|
||||
.umb-icon {
|
||||
display: inline-block;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
|
||||
svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
&.large{
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
&.medium{
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
&.small{
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
&:before, &:after {
|
||||
content: none !important;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,6 @@
|
||||
}
|
||||
|
||||
.umb-iconpicker-item i {
|
||||
font-family: inherit;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
|
||||
@@ -234,3 +234,7 @@
|
||||
.umb-media-grid__list-view .umb-table-cell.umb-table__name .item-name {
|
||||
white-space:normal;
|
||||
}
|
||||
.umb-media-grid__list-view .umb-table-cell.umb-table__name ins {
|
||||
text-decoration: none;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@
|
||||
* @description
|
||||
* The controller for the content type editor icon picker
|
||||
*/
|
||||
function IconPickerController($scope, $http, $sce, localizationService, iconHelper) {
|
||||
function IconPickerController($scope, localizationService, iconHelper) {
|
||||
|
||||
var vm = this;
|
||||
|
||||
@@ -42,19 +42,11 @@ function IconPickerController($scope, $http, $sce, localizationService, iconHelp
|
||||
vm.loading = true;
|
||||
|
||||
setTitle();
|
||||
|
||||
iconHelper.getAllIcons()
|
||||
.then(icons => {
|
||||
vm.icons = icons;
|
||||
vm.loading = false;
|
||||
|
||||
iconHelper.getLegacyIcons()
|
||||
.then(icons => {
|
||||
if(icons && icons.length > 0) {
|
||||
vm.icons = icons.concat(vm.icons);
|
||||
}
|
||||
});
|
||||
});
|
||||
iconHelper.getIcons().then(function (icons) {
|
||||
vm.icons = icons;
|
||||
vm.loading = false;
|
||||
});
|
||||
|
||||
// set a default color if nothing is passed in
|
||||
vm.color = $scope.model.color ? findColor($scope.model.color) : vm.colors.find(x => x.default);
|
||||
@@ -96,7 +88,7 @@ function IconPickerController($scope, $http, $sce, localizationService, iconHelp
|
||||
}
|
||||
|
||||
function submit() {
|
||||
if ($scope.model && $scope.model.submit) {
|
||||
if ($scope.model && $scope.model.submit) {
|
||||
$scope.model.submit($scope.model);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,10 +45,10 @@
|
||||
|
||||
<div class="umb-control-group" ng-show="!vm.loading && filtered.length > 0 ">
|
||||
<ul class="umb-iconpicker" ng-class="vm.color.value" ng-show="vm.icons">
|
||||
<li class="umb-iconpicker-item" ng-class="{'-selected': icon.name == model.icon}" ng-repeat="icon in filtered = (vm.icons | filter: searchTerm | orderBy:'name') track by $id(icon)">
|
||||
<button type="button" title="{{icon.name}}" ng-click="vm.selectIcon(icon.name, vm.color.value)">
|
||||
<umb-icon class="umb-iconpicker-svg {{icon.name}} large" icon="{{icon.name}}" svg-string="icon.svgString"></umb-icon>
|
||||
<span class="sr-only"><localize key="buttons_select">Select</localize> {{icon.name}}</span>
|
||||
<li class="umb-iconpicker-item" ng-class="{'-selected': icon == model.icon}" ng-repeat="icon in filtered = (vm.icons | filter: searchTerm) track by $id(icon)">
|
||||
<button type="button" title="{{icon}}" ng-click="vm.selectIcon(icon, vm.color.value)">
|
||||
<i class="{{icon}} large" aria-hidden="true"></i>
|
||||
<span class="sr-only"><localize key="buttons_select">Select</localize> {{icon}}</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -69,9 +69,9 @@
|
||||
prevent-default>
|
||||
Last Updated
|
||||
<i class="umb-table-head__icon icon" aria-hidden="true" ng-class="{'icon-navigation-up': isSortDirection('updateDate', 'asc'), 'icon-navigation-down': isSortDirection('updateDate', 'desc')}"></i>
|
||||
</button>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="umb-table-body">
|
||||
@@ -79,15 +79,15 @@
|
||||
|
||||
<div class="umb-table-cell">
|
||||
<i ng-show="item.selected" class="umb-table-body__icon umb-table-body__checkicon icon-check" aria-hidden="true"></i>
|
||||
<i class="{{item.icon}}" aria-hidden="true" ng-if="!item.thumbnail && item.extension != 'svg' && !item.selected"></i><i class="icon-picture" aria-hidden="true" ng-if="item.thumbnail && !item.selected"></i>
|
||||
<i class="{{item.icon}}" class="umb-table-body__icon" aria-hidden="true" ng-if="!item.thumbnail && item.extension != 'svg' && !item.selected"></i><i class="icon-picture" aria-hidden="true" ng-if="item.thumbnail && !item.selected"></i>
|
||||
</div>
|
||||
<div class="umb-table-cell umb-table__name">
|
||||
|
||||
|
||||
<ins ng-show="item.isFolder" ng-class="{'-locked': item.selected || !item.file || !item.thumbnail}" ng-click="clickItemName(item, $event, $index)" class="icon-navigation-right"></ins> <span data-src="{{item.value.src}}" class="item-name">{{item.name}}</span>
|
||||
</div>
|
||||
<div class="umb-table-cell">
|
||||
<span class="muted small" style="font-size:0.8em">{{item.updateDate | date:'medium'}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user