Test an .js.erb file with Rails + Webpacker + Jest - ruby-on-rails

I have a Rails 5 app which uses webpacker, with a file app/javascript/packs/components/module_one.js which I'm trying to test with Jest. This file contains an import to an .js.erb file as follows:
// app/javascript/packs/components/module_one.js
import ModuleTwo from './module_two.js.erb'
// ...
module_two.js.erb contains the following:
// app/javascript/packs/components/module_two.js.erb
import ModuleOne from './module_one'
// ...
While running webpack-dev-server everything works as expected, but when I try to run yarn test, it complains with the following error:
FAIL app/javascript/test/module_one.test.js
● Test suite failed to run
/path/to/module_two.js.erb:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import ModuleOne from './module_one'
^^^^^^
SyntaxError: Unexpected token import
at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:306:17)
at Object.<anonymous> (app/javascript/packs/components/module_one.js:1:745)
at Object.<anonymous> (app/javascript/test/module_one.test.js:1:124)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 2.545s
Ran all test suites.
error Command failed with exit code 1.
So it seems like the module_two.js.erb file is not being transformed properly from ES6, because when I remove the first line of module_one.js, it doesn't complain anymore.
Here is my current setup:
// .babelrc
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": "> 1%",
"uglify": true
},
"useBuiltIns": true
}]
],
"plugins": [
"syntax-dynamic-import",
["transform-class-properties", { "spec": true }]
],
"env": {
"test": {
"plugins": ["transform-es2015-modules-commonjs"]
}
}
}
// package.json
{
// ...
"devDependencies": {
"babel-jest": "^21.0.2",
"jest": "^21.0.2",
"regenerator-runtime": "^0.11.0",
"webpack-dev-server": "^2.7.1"
},
"scripts": {
"test": "jest"
},
"jest": {
"roots": [
"<rootDir>/app/javascript/test"
],
"moduleDirectories": [
"<rootDir>/node_modules"
],
"moduleFileExtensions": [
"js",
"jsx",
"erb"
],
"transform": {
"^.+\\.jsx?$": "babel-jest",
"ˆ.+\\.jsx?.erb": "rails-erb-loader"
}
}
}

In case someone else bumps into this.
Your .babelrc seems to be missing "es2015" preset.
Here is well explained about this and other issues configuring JS testing with Rails + Webpacker.

Related

how to integrate ngx-logger into playwright

I'm new in TS & angular. Now I have a legacy playwright project, which I'd like to use ngx-logger for logging.
According to many ngx-logger tutorials, I know there might be 3 steps to integrate:
install ngx-logger
npm install --save ngx-logger
import the library in the root module, i.e., app.module.ts
import { LoggerModule, NgxLoggerLevel } from 'ngx-logger';
import LoggerModule.forRoot in your application module. This is where we can configure the logger:
#NgModule({
imports: [
BrowserModule,
HttpClientModule,
LoggerModule.forRoot({
serverLoggingUrl: 'http://localhost:4201/', // Replace with YOUR API
level: NgxLoggerLevel.TRACE,
serverLogLevel: NgxLoggerLevel.ERROR,
disableConsoleLogging: false
})
],
declarations: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule { }
So finally, we can start logging anywhere in the application:
export class AppComponent {
constructor(private logger: NGXLogger) {
this.logger.debug("Debug message");
this.logger.info("Info message");
this.logger.log("Default log message");
this.logger.warn("Warning message");
this.logger.error("Error message");
}
}
However, I'm stuck in step 2&3, because I don't know where to setup these in a playwright project.
In my playwright project, I only have config files like:
~/playwright.config.ts
~/src/config/launch.config.ts
~/src/config/testrunner.config.ts
none of them contains #NgModule I could inject the codes.
Can anyone give me some hints with how to proceed?
Thank in advance.
package.json
{
"name": "portal-test",
"version": "0.0.0",
"private": true,
"description": "Portal Test Automation Suite",
"homepage": "./",
"dependencies": {
"dotenv": "^16.0.0",
"eml-parser": "^1.0.6",
"expect-playwright": "^0.7.1",
"moment": "^2.29.4",
"ngx-logger": "^5.0.11",
"npm": "^7.19.1",
"path": "^0.12.7",
"pdf.js-extract": "^0.1.5",
"pdfreader": "^1.2.11",
"playwright-core": "^1.15.2",
"request-promise": "^4.2.6",
"ts-node": "^10.3.0",
"typescript": "^4.4.3",
"yarn": "^1.22.10"
},
"scripts": {
"compile": "npx tsc --incremental -p tsconfig.json",
"test": "CI_TEST_ENV=uat npx playwright test --config=src/config/testrunner.config.ts --headed",
"test-local": "CI_TEST_ENV=local npx playwright test --config=src/config/testrunner.config.ts --headed",
"test-local-headless": "CI_TEST_ENV=local npx playwright test --config=src/config/testrunner.config.ts",
"test-dev": "CI_TEST_ENV=dev npx playwright test --config=src/config/testrunner.config.ts --headed",
"test-uat": "CI_TEST_ENV=uat npx playwright test --config=src/config/testrunner.config.ts --headed"
},
"devDependencies": {
"#playwright/test": "^1.28.1",
"playwright": "^1.15.2"
},
"extends": []
}

Import npm packages

How should I import npm packages? If I just add lodash bundling goes from 6ms to 900ms!?
Is there no way to cache static dependencies?
If I add lodash to external, globals and customResolveOptions in rollup.config.js it is excluded from the bundle. But how could I add it in a libs.js file for example?
Here are my files:
app.js
import _ from 'lodash'
alert(_.concat(["hi", "hello"]))
rollup.config.js
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import uglify from 'rollup-plugin-uglify';
import babel from 'rollup-plugin-babel';
const production = !process.env.ROLLUP_WATCH;
export default {
input: 'src/index.js',
output: {
file: 'scripts/bundle.js',
format: 'iife',
sourcemap: true
},
plugins: [
resolve(),
commonjs(),
babel({
exclude: 'node_modules/**'
}),
production && uglify()
]
};
package.json
{
"devDependencies": {
"npm-run-all": "^4.1.2",
"rollup": "^0.55.5",
"rollup-plugin-commonjs": "^8.0.2",
"rollup-plugin-node-resolve": "^3.0.0",
"rollup-plugin-uglify": "^3.0.0",
"babel-core": "^6.26.3",
"babel-plugin-external-helpers": "^6.22.0",
"babel-preset-env": "^1.7.0",
"rollup-plugin-babel": "^3.0.4"
},
"dependencies": {
"lodash": "^4.17.10"
},
"scripts": {
"build": "rollup -c",
"watch": "rollup -c -w",
"dev": "npm-run-all --parallel watch"
},
...
}
You can manually separate the entrypoints for "libs" and source code to speed up your build:
rollup.config.js
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import uglify from 'rollup-plugin-uglify';
import babel from 'rollup-plugin-babel';
const production = !process.env.ROLLUP_WATCH;
export default [{
input: 'src/index.js',
output: {
file: 'scripts/bundle.js',
format: 'iife',
sourcemap: true,
globals: {
'lodash': '_',
},
},
external: ['lodash'],
plugins: [
babel(),
production && uglify()
]
}, {
input: 'src/common.js',
output: {
file: 'scripts/common.js',
format: 'umd',
name: 'window',
extend: true,
sourcemap: true
},
plugins: [
resolve(),
commonjs(),
production && uglify()
]
}];
common.js
export { default as _ } from 'lodash'
It does add the overhead of maintaining the common.js file with libraries. Personally, I find it gives the best control over file size and compile time. If you're constantly installing and including new npm packages, this will be be hard to maintain.

Symfony flex (3.4) throws autowire issue with php based configuration in service and routes

My team working on symfony flex project. Its bit new to us. My composer file :
{
"type": "project",
"license": "proprietary",
"minimum-stability": "dev",
"require": {
"php": "^7.1",
"symfony/console": "^3.4",
"symfony/flex": "^1.0",
"symfony/framework-bundle": "^3.4",
"symfony/lts": "^3",
"symfony/yaml": "^3.4",
"guzzlehttp/guzzle": "~6.0",
"league/flysystem-aws-s3-v3": "^1.0",
"oneup/flysystem-bundle": "^2.0",
"php-amqplib/rabbitmq-bundle": "^1.13"
},
"require-dev": {
"symfony/dotenv": "^3.4",
"behat/behat": "^3.4",
"behat/symfony2-extension": "^2.1",
"mockery/mockery": "^1.0",
"phpunit/phpunit": "^6.4"
},
"config": {
"preferred-install": {
"*": "dist"
},
"sort-packages": true
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"App\\Tests\\": "tests/"
}
},
"scripts": {
"auto-scripts": {
"cache:clear": "symfony-cmd"
},
"post-install-cmd": [
"#auto-scripts"
],
"post-update-cmd": [
"#auto-scripts"
]
},
"conflict": {
"symfony/symfony": "*"
},
"extra": {
"symfony": {
"id": "01BY8F14MYNYFXEQV8P8QRJQHS",
"allow-contrib": false
}
}
}
When I run composer install I got below error:
Script cache:clear returned with error code 1
!! PHP Warning: Module 'apcu' already loaded in Unknown on line 0
!!
!! In DefinitionErrorExceptionPass.php line 37:
!!
!! Cannot autowire service "App\Services\ApiRequestValidator": argument "$secr
!! et" of method "__construct()" must have a type-hint or be given a value exp
!! licitly.
!!
!!
!!
While doing composer install we observed the symfony creates service.yaml file inside the config folder. Where as we wanted to use only php based configurations as defined at PHP-based configuration for services and routes.
If I delete the service.yaml files and run again the composer install it works well.
I am not sure why symfony creates explicitly service.yaml file when I have already php based service configuration inside my config folder.
This blocks me to up my docker container as well.

Installing Isotope + packery-mode with Bower

I'm trying to install packery-mode with bower. I have this bower.json:
"dependencies": {
"isotope": "^3.0.4",
"isotope-packery": "^2.0.0"
},
"overrides": {
"isotope": {
"main": [
"./dist/isotope.pkgd.js"
],
"dependencies": {}
},
"isotope-packery": {
"main": [
".packery-mode.pkgd.js"
],
"dependencies": {}
},
}
}
And the isotope init:
var $grid = $('.grid').isotope({
layoutMode: 'packery',
itemSelector: '.post'
});
I get an Uncaught Error: No layout mode: packery in the console. Why? packery-mode is present in the main.js (masonry layout works fine).
There was just a typo: missing slash in overrides.
".packery-mode.pkgd.js"
instead
"./packery-mode.pkgd.js"
Sorry for the noise

Loading jEditable library in Webpack

I tried to include jQuery plugin Jeditable as a webpack module from bower. I use bower-webpack-plugin to include some libraries, but it doesn't work in this case.
Edit: I use this webpack config.
webpack.config.js
const BowerWebpackPlugin = require("bower-webpack-plugin");
module.exports = {
entry: './src/script/index.jsx',
output: {
filename: 'bundle.js',
publicPath: 'http://localhost:8090/assets'
},
devtool: 'evil-source-map',
module: {
loaders: [
{
test: /\.js[x]?$/,
loaders: ['react-hot', 'jsx', 'babel'],
exclude: /node_modules/
},
{
test: /\.scss$/,
loaders: [ 'style', 'css?sourceMap', 'sass?sourceMap' ]
}
]
},
plugins: [
new BowerWebpackPlugin()
],
externals: {
'react': 'React'
},
resolve: {
extensions: ['', '.js', '.jsx']
}
}
bower.json
{
"name": "Won",
"version": "0.0.1",
"description": "Internal app",
"main": "index.js",
"authors": [
"and"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"devDependencies": {
"jquery": "~2.1.4",
"babel-polyfill": "~0.0.1",
"bootstrap": "~3.3.5",
"col-resizable": "*",
"datatables": "~1.10.8",
"immutable": "~3.7.4",
"jeditable": "~1.7.3",
"jquery-resizable-columns": "~0.2.3",
"jquery-ui": "~1.11.4",
"kefir": "~2.8.0",
"lodash": "~3.10.1"
}
}
At first I get error:
Uncaught TypeError: $(...).find(...).editable is not a function
Then I tried to add Jeditable plugin
var editable = require('jeditable') or
var editable = require('jquery.jeditable')
but i get errors like
Module not found: Error: Cannot resolve module 'jeditable' in ...
Then I tried
var editable = require('../../bower_components/jeditable/jquery.jeditable')
I get error
Uncaught ReferenceError: jQuery is not defined
(anonymous function) # jquery.jeditable.js:494
Then I tried to add Jquery:
var jQuery = require('../../bower_components/jeditable/js/jquery')
var editable = require('../../bower_components/jeditable/jquery.jeditable')
but I get error:
./bower_components/jeditable/js/jquery.js
Module build failed: SyntaxError: /Users/an/Won_webpack_25_08/bower_components/jeditable/js/jquery.js: 'with' in strict mode (2907:13)
2905 | var left = 0, top = 0, elem = this[0], results;
2906 |
> 2907 | if ( elem ) with ( jQuery.browser ) {
| ^
2908 | var absolute = jQuery.css(elem, "position") == "absolute",
2909 | parent = elem.parentNode,
2910 | offsetParent = elem.offsetParent,
When I add window.jQuery = $; it works now

Resources