I have a situation where I want to run some protractor tests in parallel in order to save time taken to run the tests. The difficulty I have is that some of these tests can't be run in parallel as the results in 1 browser are affecting the expected results in another session.
Is it possible to set my protractor config file in order to be able to do this? My current setup is shown below but this isn't working:
multiCapabilities: [
//tests run sequentially
{'browserName': 'firefox', specs: ['e2e/DynamicUpdates/**/*.spec.js'], maxInstances: 1, exclude: ['e2e/main/**/*.spec.js']},
{'browserName': 'chrome', specs: ['e2e/DynamicUpdates/**/*.spec.js'], maxInstances: 1, exclude: ['e2e/main/**/*.spec.js']},
{'browserName': 'internet explorer', specs: ['e2e/DynamicUpdates/**/*.spec.js'], maxInstances: 1, exclude: ['e2e/main/**/*.spec.js']},
{'browserName': 'safari', specs: ['e2e/DynamicUpdates/**/*.spec.js'], maxInstances: 1, exclude: ['e2e/main/**/*.spec.js']},
// Main tests - run in parallel
{'browserName': 'chrome', 'chromeOptions': {args: ['--start-maximized']}, shardTestFiles: true, maxInstances: 3},
{'browserName': 'firefox', shardTestFiles: true, maxInstances: 3},
{'browserName': 'safari', shardTestFiles: true, maxInstances: 3},
{
'browserName': 'internet explorer',
'binary': 'C:/Program Files (x86)/Internet Explorer/iexplore.exe',
'ensureCleanSession': true,
'nativeEvents': false,
'ignoreProtectedModeSettings': true,
'disable-popup-blocking': true,
'enablePersistentHover': true,
shardTestFiles: true,
maxInstances: 3
},
// Performance tests (currently not run against IE due to webdriver issues)
{'browserName': 'chrome', specs: ['/**/*.spec.js'] },
{'browserName': 'firefox', specs: ['/**/*.spec.js'] },
],
maxSessions: 3,
In the specs array, type out the files in order that you want them to run in. Or keep it the way it is and change the names of the files so they run in the proper sequence.
{'browserName': 'firefox',
specs: ['e2e/DynamicUpdates/folder1/testA.spec.js', 'e2e/DynamicUpdates/folder1/testB.spec.js', 'e2e/DynamicUpdates/folder1/testC.spec.js'],
maxInstances: 1, exclude: ['e2e/main/**/*.spec.js']},
Related
So I've been searching for a solution to this issue. My solution will not build via the command npm run build as I have the error:
JSX elements with no children must be self-closing.
There is a similar issue here with no accepted (or working) answers: JSX elements with no children must be self-closing
The associated Typescript/HTML is of the format:
class ExampleClass {
render() {
return <div>
<div>
<div>Content 1</div>
<div>Content 2</div>
<div>Content 3</div>
</div>
</div>;
}
}
export default ExampleClass;
The "error" occurs on line 5 which is:
<div>Content 1</div>
I'm using Tslint and have a number of the features of Tslint already changed / working in the file tslint.json.
See the tslint.json file as it currently stands:
{
"extends": ["tslint:recommended", "tslint-react", "tslint-config-prettier"],
"linterOptions": {
"exclude": [
"gulpfile.js",
"bin/**",
"wwwroot/**",
"config/**/*.js",
"node_modules/**"
]
},
"rules": {
"prefer-const": false,
"triple-equals": false,
"jsx-no-lambda": false,
"object-literal-shorthand": false,
"no-shadowed-variable": false,
"ban-types": false,
"one-variable-per-declaration": false,
"callable-types": false,
"quotemark": [ false, "single", "jsx-double" ],
"indent": [ true, "spaces", 2 ],
"interface-name": false,
"ordered-imports": false,
"object-literal-sort-keys": false,
"no-consecutive-blank-lines": false,
"comment-format": false,
"no-trailing-whitespace": false,
"one-line": false,
"max-classes-per-file": false,
"jsx-boolean-value": false,
"no-empty-interface": false,
"variable-name": [ true, "allow-pascal-case", "allow-snake-case" ],
"no-console": false,
"interface-over-type-literal": false
}
}
Here are the various things I've tried (consecutively, not all at once) - with no success:
"prefer-const": [
true,
{ "destructuring": "all" }
],
"react/self-closing-comp": "off",
"react/self-closing-comp": false,
"no-trailing-whitespace": false
The rules for Tslint can be found here: TSLint core rules
What I'm not looking to do is:
Completely disable TSLint
Modify my HTML structure unless totally necessary
What I'm looking for is the correct Tslint rule to use to suppress this error.
E.g. "react/self-closing-comp": false.
Hopefully someone out there has seen this before & can give me a hand!
Many thanks!
According to the npmjs.com as of the 20/01/2020:
TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint-react/issues/210 for more information.
You can configure your existing TSLint solution to use the new rules from ESLint, this is done like so:
According to npmjs.com, install ESLint with the npm command: npm install eslint --save-dev
According to npmjs.com, allow the ESLint rules by running the following command: npm install --save-dev tslint-eslint-rules
Modify your tslint.json file by adding an extends property, like so: "extends": [ "tslint-eslint-rules"]
A good number of relevant ESLint rules are found here: ESLint Rules - npmjs.com and here ESLint Rules - eslint.org
The relevant rule to fix the error:
JSX elements with no children must be self-closing.
was this:
"jsx-self-close": false
My final tslint.json file looked like this:
{
"extends": [ "tslint-eslint-rules", "tslint:latest", "tslint-react", "tslint-config-prettier" ],
"linterOptions": {
"exclude": [
"gulpfile.js",
"bin/**",
"wwwroot/**",
"config/**/*.js",
"node_modules/**"
]
},
"rules": {
"jsx-self-close": false,
"jsx-wrap-multiline": false,
"no-constant-condition": true,
"no-unused-expression": false,
"no-unused-variable": false,
"no-string-throw": false,
"prefer-const": false,
"triple-equals": false,
"jsx-no-lambda": false,
"object-literal-shorthand": false,
"no-shadowed-variable": false,
"ban-types": false,
"one-variable-per-declaration": false,
"callable-types": false,
"quotemark": [ false, "single", "jsx-double" ],
"indent": [ true, "spaces", 2 ],
"interface-name": false,
"ordered-imports": false,
"object-literal-sort-keys": false,
"no-consecutive-blank-lines": false,
"comment-format": false,
"no-trailing-whitespace": false,
"one-line": false,
"max-classes-per-file": false,
"jsx-boolean-value": false,
"no-empty-interface": false,
"variable-name": false,
"no-console": false,
"interface-over-type-literal": false,
"no-conditional-assignment": false,
"only-arrow-functions": false,
"no-var-keyword": false,
"no-empty": false,
"no-submodule-imports": false,
"no-duplicate-imports": false,
"no-useless-rename": false,
"no-implicit-dependencies": false,
"no-return-await": false,
"no-object-literal-type-assertion": false,
"prefer-object-spread": false,
"prefer-conditional-expression": false,
"jsdoc-format": false,
"prefer-for-of": false,
"radix": false
}
}
Hopefully this saves someone some time!
I spent quite some time trying to figure this out myself but here I am, with no more options to consider than to reach out to the community for some guidance.
I am trying to do something very simple in principle, dynamically import a component with WebPack, using ES6 modules and babelrc.
I have the following app architecture:
-root
-- root/.webpack.dev.js
-- root/.webpack.prod.js
-- root/.babelrc
-- root/package.json
-- root/node_modules/
-- root/dist/
-- root/src/
--- root/src/index.js
--- root/src/modules/
--- root/src/modules/module1.js
--- root/src/modules/module2.js
--- root/src/modules/module3.js
--- root/src/modules/module4.js
--- root/src/modules/module5.js
In my module1.js (not the real name) I am using the following code to dynamically import module2.js:
async function load(configObject) {
const {
init,
requestPermissions
} = await import( /* webpackChunkName: "chunkname" */ `./module2.js`)
init(configObject)
_namespace.requestPermissions = requestPermissions;
}
My .babelrc file:
{
"presets": [
["#babel/preset-env", {
"targets": "> 0.25%, not dead"
}]
],
"plugins": ["#babel/plugin-syntax-dynamic-import",
["#babel/plugin-transform-runtime",
{
"regenerator": true
}
],
],
"comments": true
}
// "#babel/preset-env"
My Webpack config:
const path = require('path');
const webpack = require('webpack')
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin
const WorkboxPlugin = require('workbox-webpack-plugin');
const {
InjectManifest
} = require('workbox-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
entry: {
lib: "./src/index.js"
},
mode: 'development',
module: {
rules: [{
test: /\.js$/,
use: [{
loader: "babel-loader"
}],
exclude: /node_modules/
}]
},
optimization: {
minimizer: [new TerserPlugin({
test: /\.js(\?.*)?$/i,
parallel: true,
cache: true,
terserOptions: {
ecma: 8,
warnings: false,
parse: {
ecma: 8,
},
compress: {
warnings: false,
comparisons: false,
},
mangle: {
safari10: true,
},
module: false,
output: {
ecma: 5,
comments: false,
ascii_only: true,
},
toplevel: false,
nameCache: null,
ie8: false,
keep_classnames: undefined,
keep_fnames: false,
safari10: false,
},
})],
},
output: {
filename: '[name].js',
chunkFilename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: "/"
},
devServer: {
contentBase: "dist",
compress: true,
stats: {
colors: true
},
overlay: true
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('development'),
'API_URL': JSON.stringify('ENDPOINT')
}
}),
new BundleAnalyzerPlugin({
generateStatsFile: true
}),
new WorkboxPlugin.GenerateSW({
"swDest": "firebase-messaging-sw.js",
}),
new InjectManifest({
"swSrc": path.join('src', 'firebase-messaging-sw.js')
})
]
};
My package.json:
{
"name": "refactor",
"version": "1.0.0",
"description": "",
"main": "backuprefacto.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "NODE_ENV=production webpack --config=webpack.prod.js",
"build:dev": "webpack --config=webpack.dev.js",
"start": "webpack-dev-server --config=webpack.dev.js"
},
"keywords": [],
"private": true,
"license": "ISC",
"devDependencies": {
"#babel/plugin-syntax-dynamic-import": "^7.2.0",
"#babel/preset-env": "^7.5.5",
"babel-loader": "^8.0.6",
"babel-minify": "^0.5.1",
"babel-minify-webpack-plugin": "^0.3.1",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"terser-webpack-plugin": "^1.4.1",
"uglifyjs-webpack-plugin": "^2.2.0",
"webpack": "^4.39.2",
"webpack-bundle-analyzer": "^3.4.1",
"webpack-cli": "^3.3.7",
"webpack-dev-server": "^3.8.0",
"workbox-webpack-plugin": "^4.3.1"
},
"dependencies": {
"#babel/core": "^7.5.5",
"#babel/plugin-transform-runtime": "^7.5.5",
"#babel/runtime": "^7.5.5",
"firebase": "^6.4.0",
"save": "^2.4.0"
}
}
I have checked all my modules, none of them expect for module1.js are calling module2.js.
I have also explored the option of webpack comments being deleted by babel and therefore added a comments: true to make sure the webpackChunkName is not being deleted but in the end, the only thing that gets built is my lib.js, not the lib.bundle.js that I expect.
I have also tried to remove all the TerserPlugin bit to check if that could have the same impact but nothing changed there.
In the need, what I am looking for is simply to have the module2.js loaded whenever it is invoked, and I therefore expect a new network request to materialise this.
Well, it turns out that if you want to use dynamic imports you need to make sure first that you are not importing at all the module at the top....
In module1.js I was importing twice, once at the top, the "regular way", once the dynamic way which was obviously leading to module2.js being consistently loaded.
I resolve my problem by modify .babelrc, modules: false
["#babel/preset-env", {
"loose": true,
"useBuiltIns": "usage",
"corejs": 3,
"modules": false
}],
I am trying to run multiple browsers in parallel using browser stack but it does not seem possible with it. This is is my config file
exports.config = {
capabilities: {
'browserstack.user' : 'abc2',
'browserstack.key' : 'asdasdasdasdj',
// Needed for testing localhost
'browserstack.local' : 'false',
multiCapabilities: [
{
browserName: 'Safari',
browser_version: '8.0',
os: 'OS X',
os_version: 'Yosemite'
},
{
browserName: 'Firefox',
browser_version: '30.0',
os: 'Windows',
os_version: '7'
},
{
browserName: 'iPhone',
platform: 'MAC',
device: 'iPhone 5S'
}
]
},
When i run - npm run protractor, i get this error Target browser must be a string, but is ; did you forget to call forBrowser()?
You need to specify browserName capability under capabilities block. Below is a working sample
exports.config = {
'specs': [ '../specs/single.js' ],
'seleniumAddress': 'http://hub-cloud.browserstack.com/wd/hub',
'commonCapabilities': {
'browserstack.user': process.env.BROWSERSTACK_USERNAME || 'BROWSERSTACK_USERNAME',
'browserstack.key': process.env.BROWSERSTACK_ACCESS_KEY || 'BROWSERSTACK_ACCESS_KEY',
'build': 'protractor-browserstack',
'name': 'parallel_test',
'browserstack.debug': 'true',
'browserName': 'Chrome'
},
'multiCapabilities': [{
'browserName': 'Chrome'
},{
'browserName': 'Safari'
},{
'browserName': 'Firefox'
},{
'browserName': 'IE'
}]
};
// Code to support common capabilities
exports.config.multiCapabilities.forEach(function(caps){
for(var i in exports.config.commonCapabilities) caps[i] = caps[i] || exports.config.commonCapabilities[i];
});
The 'browserName': 'Chrome' capability will later be overriden by your multiCapabilities block.
I've been trying multiple times to configure webpack. Everytime I start the process, auto reload works fine all the way, until I enable --hot for web-dev-server, then any change to the html has no impact, no errors, nothing, just a log in terminal that there's been a change, and a log on browser console that there's nothing to update. Hot reload works fine for CSS and JS, and I understand HTML doesn't support HMR but at least expected auto refresh to keep working ...
My configuration below:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlWebpackHarddiskPlugin = require('html-webpack-harddisk-plugin');
const webpack = require('webpack');
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'app.js',
path: path.resolve(__dirname, 'dist'),
},
plugins: [
new HtmlWebpackPlugin({
title: 'Hello world',
template: 'src/views/index.html',
alwaysWriteToDisk: true
}),
new HtmlWebpackHarddiskPlugin(),
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin()
],
devtool: 'inline-source-map',
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
hot: true,
inline: true,
open: true,
},
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader',
]
}
]
}
};
My scripts in package.json
"scripts": {
"dev": "webpack-dev-server --config webpack.config.js",
"prod": "cross-env NODE_ENV=production webpack -p --config webpack.config.js"
},
I am not sure if this is the "right" way to achieve it. But this is working for me with the following amends.
devServer: {
**contentBase: resolve('src/views'),**
open: true,
hot: true,
stats: "errors-only",
overlay: true,
**watchContentBase: true**
},
This does not seem to make sense to me but, if you set watchContentBase to true and point the contentBase to "dist", you lose HMR and any changes (event to css/js files) will cause a full reload which is not what I was aiming for.
my src structure below:
/ src
- images
- js
- sass
- views
I had also a look at vue-cli which seems to suffer from the same issue. Any changes to the index.html are not reflected (does not trigger a full page reload).
We're having trouble testing our polymer elements with web-component-tester and Sauce Labs. When we try to test with more browsers than our subscription level allows to run simultaneously, the tests that don't run immediately eventually time out. It seems really wrong that sauce labs and/or WCT doesn't know how to wait to begin executing a test until the other tests are finished, so that we can queue up as many tests as we wish without having to worry about VM utilization.
Has anyone figured this out? Thanks.
Here is our wct.conf.js in case it helps:
module.exports = {
testTimeout: 600 * 1000,
persistent: false,
ttyOutput: false,
verbose: false,
expanded: true,
browserOptions: {
name: "TWT Component Tests"
},
suites: [
'elements/twt-elements/test/index.html'
],
root: 'app',
webserver: {
pathMappings: [
{'/secrets.json': '../db/secrets.json'},
],
},
plugins: {
local: {
disabled: false,
browsers: ['chrome', 'safari', 'canary', 'firefox']
},
sauce: {
disabled: false,
commandTimeout: 600,
idleTimeout: 180,
browsers: [
/* see https://docs.saucelabs.com/reference/platforms-configurator */
/* support matrix: https://docs.google.com/spreadsheets/d/1XqTxODsi2s2GGllld1yHImtb-2ubCX1XbRsvZ4DqpZI */
{
browserName: "chrome",
platform: "OS X 10.9",
version: "40"
},
{
browserName: "safari",
platform: "OS X 10.9",
version: "7.0"
},
{
browserName: "safari",
platform: "OS X 10.10",
version: "8.0"
},
{
browserName: "chrome",
platform: "Windows 8.1",
version: "40"
},
{
browserName: "internet explorer",
platform: "Windows 8.1",
version: "11.0"
},
{
browserName: "firefox",
platform: "Windows 7",
version: "27.0"
},
{
browserName: "internet explorer",
platform: "Windows 7",
version: "10.0"
},
]
}
}
};