getMultiCapabilities seems not working with arrow function. So I defined 'getMultiCapabilities' function rather than 'multiCapabilities' property in the protractor config.ts like this:
export let config: Config = {
...
getMultiCapabilities: () => { // this doesn't work;
... // replacing it with "function() {" is okay
},
beforeLaunch: () => { // this works fine
...
},
...
}
This results in "Error: Debug Failure. False expression: position cannot precede the beginning of the file". Replacing arrow with 'function' works fine. Is this a protractor bug? or did I miss something?
Related
How do I test the following v-if on my parent component using Jest?
Parent:
<div class="systemIsUp" v-if="systemStatus == true">
foo
</div>
<div class="systemIsDown" v-else>
bar
</div>
<script>
export default {
name: 'File Name',
data () {
return {
systemStatus: null,
}
},
</script>
Here is my current setup for testing if those divs render when I change the value of the systemStatus variable
Unit Test:
import { shallowMount } from '#vue/test-utils'
import FileName from 'path'
describe('FileName', () => {
//Declare wrapper for this scope
const wrapper = shallowMount(FileName)
it('Should display message saying that the system is down if "systemStatus" data variable is false', () => {
expect(wrapper.html().includes('.systemIsDown')).toBe(false)
wrapper.setData({ systemStatus: false})
expect(wrapper.html().includes('.systemIsDown')).toBe(true)
});
});
I have tried using contains and toContain instead of includes but still cannot get it to work, Jest returns the following:
expect(received).toBe(expected) // Object.is equality
Expected: true
Received: false
expect(wrapper.html().includes('.systemIsDown')).toBe(false)
wrapper.setData({ systemStatus: false })
expect(wrapper.html().includes('.systemIsDown')).toBe(true)
^
Clearly it cannot see the systemIsDown div at all and does not think it exists hence why the first expect passes but how can I get it to see the div when the systemStatus variable is updated?
Thanks
Changed around the assertion to look for specific CSS selector as follows:
wrapper.setData({ systemStatus: false})
expect(wrapper.find(".systemIsDown")).toBeTruthy()
This should work, if you want to check given DOM element has been created (or not):
expect(wrapper.find(".systemIsDown").exists()).toBe(true) // or false
more here
Trying to set up gulp to concat some CSS files.
In my gulpfile.js I have this:
const paths = {
css: {
cssForConcat: [
'./css/*.css',
'!./css/style.css',
],
}
}
But this code:
function styles () {
return gulp.src([paths.css.cssForConcat])
Returns an error:
[07:23:27] 'styles' errored after 811 μs
[07:23:27] Error: Invalid glob argument: ./css/*.css,!./css/style.css
Copying-and-pasting the constant value works OK with no error:
function styles () {
return gulp.src('./css/*.css', '!./css/style.css')
What is wrong with my constant definition?
The problem is that you passed in [['./css/*.css', '!./css/style.css']] rather than './css/*.css', '!./css/style.css', just remove the brackets around paths.css.cssForConcat and it should work as expected.
E.g.: return gulp.src(paths.css.cssForConcat)
I am trying to transpile my ES6 code via Babel, I am using the next/babel preset along with preset-env and I'm using the browsers: defaults target.
The NextJS preset comes with #babel/plugin-proposal-object-rest-spread in its plugins array, I'm wondering why I am getting an error when testing on edge that says Expected identifier, string or number, and when looking in the compiled JS for the error, I see it happens when {...t} occurs.
Here is my babel.config.js:
module.exports = {
presets: [
[
'next/babel',
{
'#babel/preset-env': {
targets: {
browsers: 'defaults'
},
useBuiltIns: 'usage'
}
}
]
],
plugins: [
'#babel/plugin-proposal-optional-chaining',
'#babel/plugin-proposal-nullish-coalescing-operator',
['styled-components', { ssr: true, displayName: true, preprocess: false }],
[
'module-resolver',
{
root: ['.', './src']
}
]
],
env: {
development: {
compact: false
}
}
};
Any help on this would be greatly appreciated!
In the end my problem was related to a package that was not being transpiled by babel. My solution was to use NextJS' next-transpile-modules plugin to get babel to transpile the package code into something that would work on the browsers I need.
Here's an example of my NextJS webpack config with the package I need transpiled specified:
const withTM = require('next-transpile-modules');
module.exports = withTM({
transpileModules: ['swipe-listener']
});
SCRIPT1028: Expected identifier, string or number error can occur in 2 situations.
(1) This error get trigger if you are using trailing comma after your last property in a JavaScript object.
Example:
var message = {
title: 'Login Unsuccessful',
};
(2) This error get trigger if you are using a JavaScript reserved word as a property name.
Example:
var message = {
class: 'error'
};
solution is to pass the class property value as a string. You will need to use bracket notation, however, to call the property in your script.
Reference:
ERROR : SCRIPT1028: Expected identifier, string or number
Currently we have a "standard" protractor.conf.js file in place. It has a chrome specific section which looks something like this:
capabilities: {
browserName: 'chrome',
chromeOptions: {
args: [
'--no-sandbox', '--window-size=1280,1480', '--window-position=800,0'
],
prefs: {
intl: {accept_languages: defaults.LANGUAGE},
},
},
}
When we run the tests locally, everything is fine.
On our CI Infrastructure we add via CLI call the headless option:
protractor protractor.conf.js --capabilities.chromeOptions.args='headless'
First everything looked fine. The tests were running with headless chrome. But we recognized that the --window-size=1280,1480 specified in the config file was not used. We removed the --capabilities from the cli call and added the headless option directly into the protractor.conf.js.
Everything was now also working fine on the CI Infrastructure. This means the --window-size specified in the config was recognized and used.
Further tests showed, that if we want to use the CLI arguments, we would need to also add the window-size to the CLI call, to get it working as it should.
Now the question itself:
Why is this like that ? Shouldn't it be possible to add additional chromeOptions.args via CLI call ? Are the chromeOptions.args from the config no longer respected when passing some chromeOptions.args via CLI ?
Yes, The CLI values will overwrite the value in conf.js.
Below is the code snippet from launcher.ts
let initFn = function(configFile: string, additionalConfig: Config) {
let configParser = new ConfigParser();
if (configFile) { // this is the protractor conf.js
configParser.addFileConfig(configFile);
}
if (additionalConfig) { // this is all cli arguments
configParser.addConfig(additionalConfig);
}
Below is the addConfig from configParser.ts
public addConfig(argv: any): ConfigParser {
this.addConfig_(argv, process.cwd());
return this;
}
private addConfig_(additionalConfig: any, relativeTo: string): void {
// All filepaths should be kept relative to the current config location.
// This will not affect absolute paths.
['seleniumServerJar', 'chromeDriver', 'firefoxPath', 'frameworkPath', 'geckoDriver',
'onPrepare']
.forEach((name: string) => {
if (additionalConfig[name] && typeof additionalConfig[name] === 'string') {
additionalConfig[name] = path.resolve(relativeTo, additionalConfig[name]);
}
});
merge_(this.config_, additionalConfig);
}
let merge_ = function(into: any, from: any): any {
for (let key in from) {
if (into[key] instanceof Object && !(into[key] instanceof Array) &&
!(into[key] instanceof Function)) {
merge_(into[key], from[key]);
} else {
into[key] = from[key];
}
}
return into;
};
Because capabilities.chromeOptions.args is Array, thus the args value in conf.js will be overwrite by value from cli in merge_ function: into[key] = from[key];
Therefor, you have to specify all chromeOptions.args from cli by using multiple --capabilities.chromeOptions.args=xxx in cli, rather than
partial.
protractor conf.js \
--capabilities.chromeOptions.args='headless' \
--capabilities.chromeOptions.args='--no-sandbox' \
--capabilities.chromeOptions.args='--window-size=1280,1480'
I dont get the following function translated to ecmascript 2015
route: {
data: function () {
return this.$http.get('/api/posts?sort=title&order=1').then(
posts=>{this.table.posts = posts.data}
);
}
},
because this isnt refering to the window object I get the
[vue-router] Uncaught error during transition: be.js:3660:7
TypeError: undefined has no properties[Learn More]be.js:16572:13
You can use certain features such as shorthand method names and slightly more compact arrow functions to make it looks more ES2015, but it won't change the functionality:
route: {
data() {
return this.$http
.get('/api/posts?sort=title&order=1')
.then(posts => { this.table.posts = posts.data });
}
},
You couldn't replace the data hook function with an arrow functions, because this would refer to the wrong context (either to window or undefined), as its this would be defined by its surrounding lexical scope and could not be overriden.