How can I stop jshint errors in my web file for globals? - angularjs

I have a protractor test script file that looks like this:
var TestPage = function () {
this.detailsTab = element(by.id('detailsTab'));
..
It's giving me a lot of errors saying element and by are not defined. Is there a way I can stop all these hint errors from appearing?

From the protractor tutorial page you can see that these globals are created by Protactor:
This uses the globals element and by, which are also created by
Protractor.
So you need a way of telling JSHint about these globals. You can do this in your configuration for JSHint. http://www.jshint.com/docs/
Inline Configuration Method
One of the ways JSHint can be configured is by using adding special inline comments. Below is an excerpt taken from the JSHint docs page that describes how to specify global using the inline comment configuration method.
globals - A directive for telling JSHint about global variables that are defined
elsewhere. If value is false (default), JSHint will consider that
variable as read-only. Use it together with the undef option.
/* global MY_LIB: false */
Update: So for protractor the inline config would be:
/* global element */
/* global by */
or as suggested by #runTarm this condensed syntax will also work:
/* global element, by */
Config File Method
You can also configure JSHint by using configuration files. Check the documentation for the different ways to specify the config file. From the docs page we the following excerpt that explains how to write the file to specify a global variable.
Configuration file is a simple JSON file that specifies which JSHint
options to turn on or off. For example, the following file will enable
warnings about undefined and unused variables and tell JSHint about a
global variable named MY_GLOBAL.
{
"undef": true,
"unused": true,
"predef": [ "MY_GLOBAL" ]
}

Here is an example .jshint file with the globals being removed:
{
"node": true,
"browser": true,
"esnext": true,
"bitwise": true,
"camelcase": true,
"curly": true,
"eqeqeq": true,
"immed": true,
"indent": 4,
"latedef": true,
"newcap": true,
"noarg": true,
"quotmark": "single",
"undef": true,
"unused": true,
"strict": true,
"trailing": true,
"smarttabs": true,
"multistr": true,
"globals": {
"after": false,
"afterEach": false,
"angular": false,
"before": false,
"beforeEach": false,
"browser": false,
"describe": false,
"expect": false,
"inject": false,
"it": false,
"jasmine": false,
"spyOn": false,
"Kinetix": false,
"$": false
}
}

the actual .jshintrc configuration for protractor
if you want to get rid of jshint warnings for protractor, updating .jshintrc is the best approach. adding global overrides per file is rather tedious.
add the following to your .jshintrc file (you should be able to add a .jshintrc file in the directory that contains your tests rather than the root/all of your source)
.jshintrc:
{
... your other jshint stuff ...
"jasmine": true,
"mocha": true,
"globals": {
"angular": false,
"browser": false,
"inject": false,
"_": false,
"driver": false,
"protractor": false,
"browser": false,
"$": false,
"$$": false,
"element": false,
"by": false,
"list": false
}
}
what this does: (you may not need jasmine/mocha depending on how you wrote your tests)
jasmine is required for things like expect
mocha is required for things like beforeEach -
the globals are other things that protractor defines on as globals - see https://github.com/angular/protractor/blob/master/lib/runner.js#L152

Related

Setting up ESLint for a Typescript Project using React, React Testing Library, and Cypress

It seems that every time I start using a new library of some sort I run into problems with ESLint, and I can never truly figure out why. I stumble through until the errors and warnings go away, and then deal with it all again later. I'm hoping that I can get some answers on how it's supposed to work here.
I have a React project that is using Typescript. We use react-testing-library for tests (with Jest types) as well as Cypress for testing (with Cypress types). Jest and Cypress will conflict as they use a lot of the same keywords but from different libraries (ie. describe, expect, context, etc.).
Furthermore, with cypress is is possible to define your own functions which will extend the global cy object that is used in all cypress tests, however this must also be typed and requires you to write your own definition files.
Everything was going well until I tried to add my own type definitions, at which point it started complaining again. (I would like to note that my project does compile and run as expected with everything I'm doing at the moment. It is simply ESLint that isn't happy).
The main issue I'm trying to solve is why the type definition doesn't seem to be included in a project. I'm receiving the following error:
Parsing error: "parserOptions.project" has been set for #typescript-eslint/parser.
The file does not match your project config: cypress\support\index.d.ts.
The file must be included in at least one of the projects provided.
As well as whether there is a better way to lay this out.
Thanks to anyone who actually takes the time to read this and make an attempt.
The folder structure looks like this:
cypress
- fixtures
- integrations
- - file.spec.ts <- Uses the custom functions in a test
- plugins
- support
- - commands.ts <- Contains my custom functions
- - index.d.ts <- Types for custom functions
- - index.ts
- .eslintrc.js (A)
- tsconfig.json (B)
src (contains all the jest tests)
.eslintrc.js (C)
tsconfig.json (D)
tsconfig.eslint.json
.eslintrc.js (A)
module.exports = {
extends: ['../.eslintrc.js'],
parserOptions: {
project: 'cypress/tsconfig.json',
},
}
tsconfig.json (B)
{
"extends": "../tsconfig.json",
"compilerOptions": {
"noEmit": true,
// be explicit about types included
// to avoid clashing with Jest types
"types": ["cypress", "cypress-axe"],
"allowJs": true
},
"include": [".eslintrc.js", "../node_modules/cypress", "./**/*"]
}
.eslintrc.js (C)
module.exports = {
parser: '#typescript-eslint/parser',
root: true,
env: {
es6: true,
node: true,
browser: true,
},
parserOptions: {
ecmaVersion: 6,
sourceType: 'module',
tsconfigRootDir: __dirname,
project: './tsconfig.eslint.json',
ecmaFeatures: {
jsx: true,
},
},
plugins: ['react', 'react-hooks', '#typescript-eslint', 'cypress'],
rules: {
'react-hooks/rules-of-hooks': 'error', // Checks rules of Hooks
...
},
}
tsconfig.json (D)
{
"compilerOptions": {
"target": "es5",
"lib": ["es6", "dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"strict": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react",
"baseUrl": "src",
"types": ["jest"]
},
"include": [
"build-system",
"src",
".eslintrc.js",
"pretty.js",
"gulpfile.js"
],
"exclude": ["node_modules", "src/*.test.ts", "src/*.test.tsx"]
}
tsconfig.eslint.json
{
// extend your base config so you don't have to redefine your compilerOptions
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": true
},
"exclude": []
}
For what it's worth, I've solved this problem. Hopefully this can be useful to someone at some point.
Essentially the solution was to get rid of the index.d.ts file, and put the types directly in the commands.ts file.
With a little help from this thread, which states:
Hi folks, this issue comment helped me work around the issue:
cypress-io/add-ypress-custom-command-in-typescript#2 (comment)
Fix seems to be declaring Cypress in the global namespace, and your
custom command definitions in there (copied from ☝️ ):
declare global {
namespace Cypress {
interface Chainable {
customCommand: typeof customCommand;
}
}
}
function customCommand(input: MyCustomClass) {
// ...
}
Cypress.Commands.add('customCommand', customCommand);
But agree that the solution suggested in the docs doesn't work
So, by adding the the following code to my commands.ts file:
declare global {
namespace Cypress {
interface Chainable<Subject> {
/**
* Custom command to wait for a specific set of network requests to finish
* #example cy.waitForData()
*/
waitForData(): Chainable<Subject>
}
}
}
as well as adding the following rule to my .eslintrc.js (C) file:
rules: {
...
'#typescript-eslint/no-namespace': ['off']
}
I was able to fix the issue.
Furthermore, if it's relevant, the isolatedModules flag will require that you add an export {} to the commands.ts file as well.

How to minify HTML code in one line Nuxt.js?

I'm wondering is it possible to minify the page source code to one line in Nuxt.js?
I think nuxt has already minified hmtl itself. learn more in https://nuxtjs.org/api/configuration-build/#html-minify.
if you want to minify css and js, try this one ini nuxt.config.js:
build: {
html:{
minify:{
collapseBooleanAttributes: true,
decodeEntities: true,
minifyCSS: true,
minifyJS: true,
processConditionalComments: true,
removeEmptyAttributes: true,
removeRedundantAttributes: true,
trimCustomFragments: true,
useShortDoctype: true,
minifyURLs: true,
removeComments: true,
removeEmptyElements: true
}
}
The answer from Prana is a step in the right direction. To minify the page source code to one line you should add as well:
preserveLineBreaks: false
collapseWhitespace: true
Note two last lines under build.html.minify in the code snippet below.
build: {
html: {
minify: {
collapseBooleanAttributes: true,
decodeEntities: true,
minifyCSS: true,
minifyJS: true,
processConditionalComments: true,
removeEmptyAttributes: true,
removeRedundantAttributes: true,
trimCustomFragments: true,
useShortDoctype: true,
preserveLineBreaks: false,
collapseWhitespace: true
}
},
}
Not sure if it is possible to minify it to one line, but you can definitely do some minification of the HTML. Check out this part of the documentation:
https://nuxtjs.org/api/configuration-build/#html-minify
According to the authors, nuxt uses https://github.com/kangax/html-minifier under the hood, and there seems to be quite a few minification options to pick from.

How to get rid of console log

I wrote a web app using React, and I build it using Webpack. But in the production build, I want to get rid of all the console log statement because I don't want people to see some information such as their UID. Is there anything I can config in Webpack so that it will automatically get rid of all the console log? I tried p flag but it didn't do that.
Try using the UglifyJsPlugin with this configuration:
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
screw_ie8: true,
conditionals: true,
unused: true,
comparisons: true,
sequences: true,
dead_code: true,
evaluate: true,
if_return: true,
join_vars: true,
drop_console: true,
drop_debugger: true,
global_defs: {
__REACT_HOT_LOADER__: undefined // eslint-disable-line no-undefined
}
},
minimize: true,
debug: false,
sourceMap: true,
output: {
comments: false
},
}),
You can see the whole config file here: https://github.com/jquintozamora/react-typescript-webpack2-cssModules-postCSS/blob/master/webpack/webpack.config.prod.js

JSHint unable to find/interpret .jshintrc file

I am using WebStorm IDE and created my angularJS project. I am also using grunt, and am using grunt-contrib-jshint. I had some options preconfigured in my .jshintrc file which were already in the angular-seed repository I used to create the project:
{
"strict": "global",
"node": true,
"globals": {
// Angular
"angular": false,
// Angular mocks
"module": false,
"inject": false,
// Jasmine
"jasmine": false,
"describe": false,
"beforeEach": false,
"afterEach": false,
"it": false,
"expect": false,
// Protractor
"browser": false,
"element": false,
"by": false
}
}
When I run grunt jshint on terminal, I get many errors, all of them related to the errors which arise when options are not set properly. However, when I copy these options and put them in my Gruntfile, everything works like a charm.
jshint: {
files: ['Gruntfile.js', 'app/**/*.js'],
options: {
// options here to override JSHint defaults
node: true,
globals: {
// Angular
angular: false,
// Angular mocks
module: false,
inject: false,
// Jasmine
jasmine: false,
describe: false,
beforeEach: false,
afterEach: false,
it: false,
expect: false,
// Protractor
browser: false,
element: false,
by: false
}
}
},
Basically, what I've understood is jshint is not reading options from the .jshintrc file. How do I solve this issue?
Set the option jshintrc for your jshint task to true.
If set to true, no config will be sent to JSHint and JSHint will search for .jshintrc files relative to the files being linted.

How to add support for angular into jshint?

I'm using webstorm and have custom config files for both jshint and jscs, in jshint I've added this params:
jshintrc:
{
"globals": {
"jasmine": true,
"angular": true,
"browser": true,
"element": true
}
}
But it still keeps highlighting angular and everything angular related.
How can I finally enable it?

Resources