gulp-less messes with global variable - less

I'm trying to pass a version string from gulp to less, as demonstrated in the following example project:
package.json:
{
"name": "webui",
"version": "0.0.0",
"private": true,
"devDependencies": {
"gulp": "^3.9.0",
"gulp-less": "^3.0.5"
}
}
gulpfile.js:
var gulp = require('gulp');
var less = require('gulp-less');
var LESS_PARAMS = {
globalVars: {
webUiVersion: '0.0.0'
}
};
gulp.task('less', function() {
return gulp.src('test.less')
.pipe(less(LESS_PARAMS))
.pipe(gulp.dest('.'))
})
test.less:
.test {
background: url("test.jpg?v=#{webUiVersion}")
}
When running gulp less, the generated test.cssfile looks like this:
.test {
background: url("test.jpg?v=0 0");
}
As you can see, gulp-less somehow transformed 0.0.0 into 0 0. If I use a simple string without dots or 0, like 123asdf, the replacement works fine. Also, directly calling
lessc --global-var='webUiVersion="0.0.0"' test.less
on the command line produces the desired result.
So my questions are:
Is this intentional behaviour or a bug?
Is there a way to work around this issue?

I've found a way to fix this issue: The trick is to enclose the string that should be passed to less in quotes, that is writing webUiVersion: '"0.0.0"' instead of webUiVersion: '0.0.0' in gulpfile.js.
The reason for this has been pointed out by seven-phases-max below: The value of webUiVersion is directly passed to less. Without the quotes, 0.0.0 is parsed as two numbers, namely 0.0 followed by .0, which results in 0 0 in the generated CSS.

Related

Docusaurus: How can I have multiple versions of different docs in the docs directory?

I'm working with Docusaurus to create a documentation site for 3 different education courses - all within the docs folder.
So I'm looking for a way to have the version be different across folders in there, or figure out what the best strategy for this is.
Right now, in my docusaurus.config.js I have:
module.exports = {
presets: [
'#docusaurus/preset-classic',
docs: {
lastVersion: 'current',
versions: {
current: {
label: '1.0.0',
path: '1.0.0',
},
},
},
],
};
But I'm not sure how to keep track of 3 different versions across 3 different docs all within the same site.
Swizzle the navbar via wrapping
yarn run swizzle #docusaurus/theme-classic NavbarItem/DocsVersionDropdownNavbarItem -- --wrap
Modify the swizzled component like so:
src/theme/NavbarItem/DocsVersionDropdownNavbarItem.js:
import React from "react";
import DocsVersionDropdownNavbarItem from '#theme-original/NavbarItem/DocsVersionDropdownNavbarItem';
import { useLocation } from '#docusaurus/router';
export default function DocsVersionDropdownNavbarItemWrapper(props) {
const { docsPluginId, className, type } = props
const { pathname } = useLocation()
/* (Custom) check if docsPluginId contains pathname
Given that the docsPluginId is 'charge-controller' and the routeBasePath is 'charge-controller', we can check against the current URI (pathname).
If the pathname contains the docsPluginId, we want to show the version dropdown. Otherwise, we don't want to show it.
This gives us one, global, context-aware version dropdown that works with multi-instance setups.
You want to declare a version dropdown for each plugin in your navbarItems config property for this to work well.
const doesPathnameContainDocsPluginId = pathname.includes(docsPluginId)
if (!doesPathnameContainDocsPluginId) {
return null
}
return <DocsVersionDropdownNavbarItem {...props} />;
}
For this to work, you need to have your documentation (based on products) split up using multi-instances: (https://docusaurus.io/docs/docs-multi-instance#docs-navbar-items)
Note that the preset docsPlugin ID always is "default".
You can try to use
import {
useActivePluginAndVersion,
} from '#docusaurus/plugin-content-docs/client';
const version = activePluginAndVersion.activeVersion.name; // use label instead of name if issues arise.
instead to get the current docsPluginId, name or label.
This would be the more "robust" solution I think. That said, we do use the solution I provided above as-is and it works fine for now.

vue-json-pretty doesn't update immedieately on data change

I have update my rather old project to 'wanted' npm packages.
And have found that reactivity is broken for same cases.
I use vue-json-pretty to show json data:
<vue-json-pretty
:path="'hypervisor'"
:data="props.item.additionalData"
:deep="packetsWithJson[props.item.packet]"
:showLength="true"
:showLine="true"
#click="handleJsonClick"
></vue-json-pretty>
...
data() {
return {
packetsWithJson: {
packet_type_1: 0,
packet_type_2: 3,
}
},
...
handleJsonClick(packet) {
this.packetsWithJson[packet] = 10;
this.jsonExpanded = true;
},
vue version: 2.7.14
It worked before, but after update all packages to 'wanted' position looks like something is broken. Please help to figure out what is the possible reason.

Prettier breaking functions in Vue script tag

I would like to keep a if function in one line without using ternary if but prettier format breaks it, I didn't find a option for that in prettier documentation
tag script inside .vue file
WANTED OUTPUT
<script>
export default {
methods: {
changeSlide(slideIndex) {
if (slideIndex >= this.slides.length) { slideIndex = 0 }
}
},
}
</script>
prettier format
<script>
export default {
methods: {
changeSlide(slideIndex) {
if (slideIndex >= this.slides.length) {
slideIndex = 0
}
}
},
}
</script>
I'm working with Nuxt(VueJS)
my prettier config:
{
"semi": false,
"singleQuote": true,
"tabWidth": 4,
"useTabs": true,
"printWidth": 120
}
You're using Prettier with a VScode extension or via ESlint? I recommend the second approach btw, for a nice linter + formatter combo.
This will also give you the right to disable linting + formatting of a specific line or block of code, so quite more flexiible overall.
If you're using the first approach, then you could maybe try this Range ignore approach.
You could use // prettier-ignore to ignore the whole thing but I doubt you can enable it back afterwards. As you saw in the options, there is nothing that can help there. But the purpose of Prettier is to be opinionated so it's legit that you don't have the whole flexibility that ESlint could bring to the table.
There are some guidelines like the one from Airbnb, this is great but then you need your whole team to agree on a specific way of writing things. Which defeats the purpose of Prettier: use it and stop discussing the style on each Pull Request once and for all, hence why it's opinionated and have not that much configurable options.
A simple (yet meh hack) would be to set "printWidth": 200, this may somehow work but not really flexible.
TLDR: use an ESlint + Prettier combo (without the VScode extension) for a fully fledged flexible configuration or let Prettier do it's opinionated formatting.

Supply Test Data into Nightwatch

I tried to supply test data to nightwatch but i don't know how. How to supply any dynamic test data to Nightwatch testing?
I don't want to hardcoded the value into the code. I want to supply it from file.
EDIT:
.setValue('selector', 'DEBBIE A/P EKU')
Since you mentioned it in one of your comments you want to read the values from a file, I recommend you doing it via pseudo-JSON (actually .js). Also a solution I applied in my company.
I have multiple json files which contain certain test data that I didn't want to have in the code. The basic structure of those looks like this:
module.exports = {
WHATEVER_IDENTIFIER_I_WANT: 'Some shiny value'
}
My Page Object contains a line like this:
const STATIC = require('path/to/static/file')
…
.setValue('selector', STATIC.WHATEVER_IDENTIFIER_I_WANT)
And yea, it is not highly sophisticated but it fulfils the purpose.
If you don't want to use module.exports and .js you can still use some node methods to load and parse a JSON. E.g.
fs.readFileSync / fs.readFile (to load the JSON file)
const file = fs.readFileSync('path/to/file')
JSON.parse() (to retrieve a JavaScript Object)
const STATIC = JSON.parse(file)
Hope this is useful for you :)
I've been through the same issue. At the moment my set up is like this:
Raw data are in the excel sheet. I use node.js to convert excel sheet into json file. Then use json data in nightwatch.
Here is the code to read the json file in nightwatch:
module.exports = {
tags: ['loginpage'],
// if not regular size logout button is not visible
'Login' : function (client) {
var credentials;
try{
credentials = require('./path/to/inputJsonData.json');
} catch(err) {
console.log(err);
console.log ('Couldn\'t load the inputJsonData file. Please ensure that ' +
'you have the inputJsonData.json in subfolder ./path/to ' +
'in the same folder as the tests');
process.exit();
}
Here is the code that use data from it:
client
.url(credentials.url)
.waitForElementVisible('body', 1000)
.assert.title('Sign In Home Page')
.login(credentials.username,credentials.password)
// some more steps here
.logout()
.end();
}
};
inputJsonData.json data
{
"url": "http://path/to/my/input/credentials/file",
"username": "yourUserName",
"password": "yourPassword"
}
My problem/question:
How to find the count of elements read into the json object from a file when the file has following format?:
[
{
....
},
{
....
},
.....
{
....
}
]
My failed attempt to get the number of elements: JSON.parse(company).count where company is another json read file like credentials in above code.
Answer: use standard javascript array property length company.length
TheBayOr answered the question concisely regarding the use of files. Just to add that if you don't literally mean a non 'code' file but simply using a different location to store the values then the most common approach is using globals.
You can place an array of values in either your nightwatch.json...
"test_settings" : {
"default" : {
"selenium_port" : 4444,
"selenium_host" : "localhost",
"silent": true,
"globals" : {
"VARIABLE_1" : "i'm a variable",
"VARIABLE_2" : "i'm a variable too"
},
"desiredCapabilities": {
"browserName": "chrome",
"javascriptEnabled": true,
"acceptSslCerts": true
}
},
"other_environment" : {
"globals" : {
"VARIABLE_1" : "i'm a different variable",
"VARIABLE_2" : "i'm a different variable too"
You can use them in tests with something like....
.url(browser.globals.VARIABLE_1)
Notice in the above you can have sets of globals under different environments. This has the advantage of meaning you can have multiple sets and use the one you want by running nightwatch -e 'my desired environment'.
Similarly this can be achieved by putting your array of data in a globals file e.g. globals.js and referencing it in your 'globals.path'.
If you want to get really into it you can even store your variables in global.js then use the 'fs' library to write the values to a file, then have your tests read from there. I'd recommend a new question if thats what you intend.
Hopefully that adds something :)
In my case I just created a function which read variables , data ,etc
more details here: https://stackoverflow.com/a/64616920/3957754

Dynamic SASS variables from a server side language

I have a database table that contains a list of colour variables (example HEX colour code). My styles are compiled using Gulp and SASS.
When my Django app creates/updates a row in the database i need to build a new stylesheet based on the colours.
Somehow i need to get the colours from my server side app into a build process.
Record with colours added -> Gulp runs -> New colour variables are used within the stylesheet generation.
Any ideas how this could be done?
Thanks,
I solved this problem in a less than ideal way..
There is a module called gulp-preprocess which take a context array and replaces vars before the sass process runs..
For example:
SASS File
$body-background: '/* #echo body-background */';
body {
background: $body-background;
}
GULP
var data = {
'1': {
'body-background': '#f00',
},
'2': {
'body-background': '#ffffff',
}
}
gulp.task('scss', function () {
for (var partner_id in data) {
if (!data.hasOwnProperty(partner_id)) continue;
var partner_data = data[partner_id]
gulp.src('./static/scss/*.scss')
.pipe($.sourcemaps.init())
.pipe($.preprocess({context: partner_data}))
.pipe($.sass({
errLogToConsole: true,
style: 'compact'
})
.on('error', function (err) {
console.log('Error:', err);
this.emit('end');
}))
.pipe($.autoprefixer({cascade: false}))
.pipe($.cssnano())
.pipe($.sourcemaps.write('./maps'))
.pipe(gulp.dest('./static/css/'+ partner_id))
}
});
I came across this service https://www.grooveui.com, that lets you create multiple themes from your SASS files.
The only catch is you have to host your SASS files with them. Then you can create new themes and set variable values. I guess they are using database to store variables and generating multiple SASS files.
Could be worth a try.