Getting a karma test to work with a static HTML file - jasmine

I've got a HTML file that I want to run some tests on:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no" />
<title>Karma Test</title>
<link rel="stylesheet" href="http://cdn.jsdelivr.net/normalize/3.0.3/normalize.css" />
</head>
<body>
<!-- Basic Buttons -->
<rui-button id="test1">Test</rui-button>
<!-- Disabled Buttons -->
<rui-button id="test2" disabled>Test</rui-button>
<rui-button id="test3" disabled="disabled">Test</rui-button>
<rui-button id="test4" disabled="{ true }">Test</rui-button>
<script src="http://cdn.jsdelivr.net/riot/2.6.2/riot.js"></script>
<script src="rui-full.js"></script>
<script>
riot.mount('*');
</script>
</body>
</html>
I've setup my karma.conf, I think correctly:
module.exports = function(config) {
config.set({
browsers: ['PhantomJS'],
frameworks: ['jasmine'],
plugins: [
'karma-jasmine',
'karma-jasmine-html-reporter',
'karma-html2js-preprocessor',
'karma-chrome-launcher',
'karma-phantomjs-launcher',
'karma-riot'
],
preprocessors: {
'**/*.html': ['html2js']
},
files: [
{ pattern: '../../build/demo/rui-full.js', included: true, watched: false, served: true },
'./**/*.html',
'./**/*.spec.js'
],
reporters: ['progress', 'kjhtml'],
singleRun: true,
html2JsPreprocessor: {
processPath: function(filePath) {
return filePath.split('/')[1];
}
}
});
};
And I've written a simple simple test:
describe('rui-button tests', function() {
beforeEach(function (done) {
document.body.innerHTML = __html__['ui-button.html'];
});
it('Create basic button', function() {
var el = document.querySelector('#test1');
expect(el).toBeTruthy();
console.log(el.innerHTML)
});
});
Now the beforEach works, and the html is set. But its not working as expected. I'm not sure if the rui-full.js script is loading or not. I don't think it is as el.innerHTML is just "Test", it's not been replaced with the riot.js tag.
Do I have things setup correctly? Is there a way to log out any errors?
I'm running my test with the cli:
karma start tests/karma.config.js

You have to mount the tags in your code like this
before(function() {
var html = document.createElement('rui-button')
document.body.appendChild(html)
tag = riot.mount('hello')[0]
});
it('mounts a rui-button tag', function() {
expect(tag).to.exist
expect(tag.isMounted).to.be.true
})
Here is a tutorial for testing Riot with mocha+chai+karma https://github.com/vitogit/tdd-mocha-chai-riot
Or if you don´t want to use karma : https://github.com/vitogit/minimalistic-riotjs-testing online version: http://plnkr.co/edit/BFOijJ?p=preview

Related

manifest.json file is not loading in production mode

I am trying to make PWA of my Vue/Laravel app. The problem I am facing is my manifest.json file is not linked to my production build head. On my development it's working fine, browser is detecting the manifest.json but not on server.
I have linked the manifest.json to my app.blade.php file but on production server when I see the source code there is no manifest.json attached.
Here is my app.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}"/>
<link rel="manifest" href="manifest.json" />
<title>{{env('APP_NAME')}}</title>
</head>
<body class="antialiased">
<div id="app"></div>
<script src="{{ asset('js/main.js') }}"></script>
</body>
</html>
My webpack.mix.js configs are
const mix = require('laravel-mix');
const path = require('path');
const WebpackPwaManifest = require('webpack-pwa-manifest');
const { WebpackManifestPlugin } = require('webpack-manifest-plugin');
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel applications. By default, we are compiling the CSS
| file for the application as well as bundling up all the JS files.
|
*/
mix.ts('resources/js/main.ts', 'public/js')
.vue({ version: 3 })
.postCss('resources/css/app.css', 'public/css', [
//
])
.sourceMaps();
mix.browserSync('http://localhost/');
mix.webpackConfig(module.exports = {
resolve: {
alias: {
'#/pages': path.resolve(__dirname, './resources/js/pages'),
'#/assets': path.resolve(__dirname, './resources/js/assets'),
},
},
});
mix.webpackConfig({
plugins: [
new WebpackManifestPlugin(),
new WebpackPwaManifest({
name: "DC",
short_name: "DC",
start_url: "/",
display: "standalone",
theme_color: "#004c97",
background_color: "#fff",
icons: [
{
"src": path.resolve(__dirname, './resources/js/assets/images/logo-pwa.png'),
"sizes": "256x256",
"type": "image/png"
}
],
id: "/#/login",
filename: 'manifest.json',
publicPath: '/',
basePath: '/public',
}),
],
});
mix.options({
hmrOptions: {
host: 'localhost',
port: 8000
}
})
Remember, it's working fine on development but not working on production.
Here is my production output
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="irPGXqkRHKDYOBD1G0rPYsNp0Iwu881BIeCbmBfo"/>
<title>Abc</title>
</head>
<body class="antialiased">
<div id="app"></div>
<script src="https://xxxx/js/main.js"></script>
</body>
</html>
As you can see, there is no manifest file attached here
After spending hours i finally able to resolve this issue by replacing assets with mix in app.blade.php here is my latest file
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}"/>
<link rel="manifest" href="{{ mix('/pwa/manifest.json') }}" />
<title>{{env('APP_NAME')}}</title>
</head>
<body class="antialiased">
<div id="app"></div>
<script src="{{ mix('/js/main.js') }}"></script>
</body>
</html>

Laravel Vue production instance

I have a Laravel Vue project that works fine in development. I have been trying to get it to our production server for some hours now. However, when I visit the URL, I get a blank page. Upon inspection in the console, I notice all the js chunk files return status of 200, but their contents are "We're sorry, but Project Name doesn't work properly without Javascript."
The following is a snippet of my webpack.mix.js.
mix
.js('resources/js/app.js', 'public/js')
.webpackConfig({
resolve: {
alias: {
'#': path.resolve(__dirname, 'frontend/src/'),
'#themeConfig': path.resolve(__dirname, 'frontend/themeConfig.js'),
'#core': path.resolve(__dirname, 'frontend/src/#core'),
'#validations': path.resolve(__dirname, 'frontend/src/#core/utils/validations/validations.js'),
'#axios': path.resolve(__dirname, 'frontend/src/libs/axios')
}
},
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
{
loader: 'sass-loader',
options: {
sassOptions: {
includePaths: ['frontend/node_modules', 'frontend/src/assets']
}
}
}
]
},
{
test: /(\.(png|jpe?g|gif|webp)$|^((?!font).)*\.svg$)/,
loaders: {
loader: 'file-loader',
options: {
name: 'images/[path][name].[ext]',
context: '../vuexy-vuejs-bootstrap-vue-template/src/assets/images'
// context: 'frontend/src/assets/images'
}
}
}
]
}
})
.sass('resources/sass/app.scss', 'public/css')
.options({
postCss: [require('autoprefixer'), require('postcss-rtl')]
})
// ------------------------------------------------
// If you are deploying on subdomain/subfolder. Uncomment the below code before running the 'yarn prod' or 'npm run production' command.
// Please Change below 'publicPath' and 'setResourceRoot' options as per your sub-directory path.
// ------------------------------------------------
if (mix.inProduction()) {
mix.version()
mix.webpackConfig({
output: {
publicPath: '/app/',
chunkFilename: 'js/chunks/[name].[chunkhash].js'
}
})
mix.setResourceRoot('/app/')
}else{
mix.webpackConfig({
output: {
chunkFilename: 'js/chunks/[name].js'
}
})
}
I set up production using the ff on my local machine:
npm run prod
Then I run the following via ssh on the server:
composer install --optimize-autoloader --no-dev
php artisan key:generate
In the console, the js chunk files show this as their response from the server:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="csrf-token" content="j9kLqaAInZ4043rRqT9Zn3kNMHaSfCdF7h5ejnnZ">
<link rel="icon" href="/favicon.ico">
<title>project Title</title>
<link rel="stylesheet" href="https://app.myprojects.com/css/app.css?id=bff15ac59733e85aedce">
<link rel="shortcut icon" href="https://app.myprojects.com/images/logo/favicon.png">
</head>
<body>
<noscript>
<strong>We're sorry but this platform doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app">
</div>
<script src="https://app.myprojects.com/js/app.js?id=a74eb61fbd09ea2e1e92"></script>
</body>
</html>
Any help would be appreciated!
Upon lots of further investigations, i noticed that both app.css and app.js loads properly and only the chunk files had the issue. Apparently they were loading from
https://app.myproject.com/app/js/chunks/1.edcb1b13fece690b424f.js
instead of from
https://app.myproject.com/js/chunks/1.edcb1b13fece690b424f.js
I was able to get the page to load properly by setting publicPath and resourceRoot to /

Kendo DataBound e.model object VS Edit e.model object

I'm using Kendo DataBound event to print the model from the row triggering the event, the problem I'm facing is the model is undefined when using DataBound different from using Edit event.
.Events(e => { e.DataBound(#<text>function(e) { alert(e.model); }</text>) })
The problem is that apparently e.DataBound is not handling the e argument as the Edit, Cancel, and the rest of events.
When trying with e.Edit(#<text>function(e) { alert(e.model); }</text>) the e.model object is loaded with the properties and values.
Is there a way to achieve this?
You can achieve that by using jQuery only:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.1.114/styles/kendo.common.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.1.114/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.1.114/styles/kendo.default.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.1.114/styles/kendo.mobile.all.min.css">
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2020.1.114/js/angular.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2020.1.114/js/jszip.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2020.1.114/js/kendo.all.min.js"></script>
<script>
$(function() {
$('#grid').kendoGrid({
dataSource: {
data: [{ A: 1, B: 2 }, { A: 3, B: 4 }]
},
});
let grid = $("#grid").data("kendoGrid");
$("#grid").on('click', 'tbody td', function(e) {
let $td = $(e.target),
dataItem = grid.dataItem($td.parent()),
cellContent = dataItem[$td.data('field')];
console.log($td, dataItem, cellContent);
});
});
</script>
</head>
<body>
<div id="grid"></div>
</body>
</html>
Demo
Or by using the grid's change event. But in order to use that event you need to set your grid selectable to true:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.1.114/styles/kendo.common.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.1.114/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.1.114/styles/kendo.default.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.1.114/styles/kendo.mobile.all.min.css">
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2020.1.114/js/angular.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2020.1.114/js/jszip.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2020.1.114/js/kendo.all.min.js"></script>
<script>
$(function() {
$('#grid').kendoGrid({
dataSource: {
data: [{ A: 1, B: 2 }, { A: 3, B: 4 }]
},
selectable: true,
change: function() {
let dataItem = this.dataItem(this.select());
console.log(dataItem);
}
});
});
</script>
</head>
<body>
<div id="grid"></div>
</body>
</html>
Demo

How to setup inertia on my project, gives me an error when I try and load the login page

I'm trying to setup Inertia to use in my Laravel project but it gives me errors? Where is my mistake?
I installed Inertia with this command
composer require inertiajs/inertia-laravel
followed the instructions on the github page and added #inertia to my app.blade.php like this:
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<!-- Scripts -->
<script src="{{ asset('js/app.js') }}" defer></script>
<link rel="icon" type="image/jpg" href="{{asset("/image/logo2.png")}}">
<!-- Fonts -->
<link rel="dns-prefetch" href="//fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">
<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
#inertia
</body>
</html>
in my Login Controller
public function showLoginForm()
{
return Inertia::render('Auth/Login');
}
in my routes/web.php
Auth::routes();
Route::get('login', 'Auth\LoginController#showLoginForm')->name('login');
Route::post('login', 'Auth\LoginController#login');
This is the error I get:
the lines that is highlighted is the #inertia which show up as this
<div id="app" data-page="<?php echo e(json_encode($page)); ?>"></div>
What am i doing wrong?
#inertia blade directive is working but not rendered because you need to install the frontend adapter
npm install #inertiajs/inertia #inertiajs/inertia-vue
Set it up in webpack.mix.js 
const mix = require('laravel-mix')
const path = require('path')
mix.js('resources/js/app.js', 'public/js')
.webpackConfig({
output: { chunkFilename: 'js/[name].js?id=[chunkhash]' },
resolve: {
alias: {
vue$: 'vue/dist/vue.runtime.esm.js',
'#': path.resolve('resources/js'),
},
},
})
And initialize it in Vue resources/js/app.js
import { InertiaApp } from '#inertiajs/inertia-vue'
import Vue from 'vue'
Vue.use(InertiaApp)
const app = document.getElementById('app')
const pages = {
'Auth/Login': require('./Pages/Auth/Login.vue').default,
}
new Vue({
render: h => h(InertiaApp, {
props: {
initialPage: JSON.parse(app.dataset.page),
resolveComponent: name => pages[name],
},
}),
}).$mount(app)

Ember qunit tests are being called twice

I recently upgraded my "ember-cli" to "2.10.0" and "ember-cli-qunit" to "3.0.1" but each test module is getting run twice. However when I try the code in jsbin I am unable to recreate the issue. My test looks like:
import Qunit from 'qunit';
Qunit.module("[Reporting]", function (hooks) {
hooks.before(function () {
console.log("before");
});
hooks.after(function () {
console.log("after");
});
Qunit.test("test 1", function (assert) {
console.log("test 1");
assert.equal(1,1);
});
Qunit.test("test 2", function (assert) {
console.log("test 2");
assert.equal(1,1);
});
}
I can see that my quint version is 2.1.1 and jquery version is 1.11.3.
My Index.html file looks like this;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Studio Tests</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
{{content-for 'head'}}
{{content-for 'test-head'}}
<link rel="stylesheet" href="assets/vendor.css">
<link rel="stylesheet" href="assets/studio-blessed1.css">
<link rel="stylesheet" href="assets/studio.css">
<link rel="stylesheet" href="assets/test-support.css">
<style>#blanket-main { position: relative; z-index: 99999; }</style>
{{content-for 'head-footer'}}
{{content-for 'test-head-footer'}}
</head>
<body>
{{content-for 'body'}}
{{content-for 'test-body'}}
<script src="assets/vendor.js"></script>
<script src="assets/test-support.js"></script>
<script src="assets/studio.js"></script>
<script src="assets/blanket-options.js"></script>
<script src="assets/blanket-loader.js"></script>
<script src="testem.js"></script>
<script src="assets/tests.js"></script>
{{content-for 'body-footer'}}
{{content-for 'test-body-footer'}}
</body>
</html>
I found the issue with my test. I was trying to configure the set of tests that would loaded based on a query parameter I send when running the tests. The way I was trying to do that basically wrong.
In my test-helper.js, I had added :
import Resolver from 'studio/resolver';
import {setResolver} from 'ember-qunit';
import TestLoader from 'ember-cli-test-loader/test-support';
setResolver(Resolver.create());
//ADDED THIS PROTOTYPE AS PER MENTIONED IN https://github.com/ember-cli/ember-cli-test-loader
TestLoader.prototype.shouldLoadModule = function(moduleName) {
//return (moduleName.match(/[-_]test$/));
var additionalCondition = true;
var dirName = QUnit.urlParams.directory;
if (dirName) {
additionalCondition = moduleName.indexOf(dirName + '/') === 0 && (moduleName.indexOf('/', dirName.length + 1) === -1);
}
return additionalCondition;
};
TestLoader.load();
But instead I had to do:
import Ember from 'ember';
import resolver from './helpers/resolver';
import {
setResolver
} from 'ember-qunit';
import TestLoader from 'ember-cli-test-loader/test-support';
Ember.$(document).ready(function () {
TestLoader.prototype.shouldLoadModule = function (moduleName) {
//return (moduleName.match(/[-_]test$/));
var additionalCondition = true;
var dirName = QUnit.urlParams.directory;
if (dirName) {
additionalCondition = moduleName.indexOf(dirName + '/') === 0 && (moduleName.indexOf('/', dirName.length + 1) === -1);
}
return additionalCondition;
};
});
setResolver(resolver);
But now I am getting following error when calling andThen helper method:
Assertion after the final `assert.async` was resolved
So:
//THIS FAILS(BUT USED TO WORK BEFORE QUINT UPGRADE)
test("DUMMY TEST 2", function (assert) {
clickSomeElement();
andThen(()=> {
assert.equal(1, 1);
});
});
I am using really classic version of ember "1.10.1". Not sure if it was caused by it! Could use some help resolving it. Posted here too: https://github.com/ember-cli/ember-cli/issues/6293

Resources