fireEvent.click() not working with mocha and jsdom - mocha.js

I have a simple test case that is failing to click the button. The button exists and is found, but firing the click event is not triggering the onClick handler for the button. Unsure if this is related to jsdom or mocha setup, but curious if anyone can get this working with this particular version of mocha?
Node: v15.12.0
Packages:
"react": "16.13.1"
"mocha": "6.2.2"
"chai": "4.2.0"
"sinon": "7.5.0"
"#testing-library/react": "^11.1.2"
"jsdom": "15.2.0"
"jsdom-global": "3.0.2"
Test case:
import React from 'react';
import { render, screen, fireEvent } from '#testing-library/react';
import { expect } from 'chai';
import { fake } from 'sinon';
describe.only('Repro', () => {
it('handles click', () => {
const onClickFake = fake(() => console.log('onClick'));
render(<button onClick={onClickFake}>Click Me</button>);
screen.debug();
fireEvent.click(screen.getByRole('button'));
expect(onClickFake.calledOnce).to.be.true;
});
});
Also, a potentially unrelated note, when I call debug with a text child element, it appears to print the DOM object instead of just showing the text. This makes debug printing for complex components useless.
Debug Print:
<body>
<div
id="root"
/>
<div>
<button>
Object {
"_data": "Click Me",
"_index": undefined,
"_nextSibling": [Circular],
"_nid": 8,
"_previousSibling": [Circular],
"nodeType": 3,
"ownerDocument": Object {
"_address": "http://localhost:3000",
"_childNodes": null,
"_contentType": "text/html",
"_firstChild": <html>
<head />
<body>
<div
id="root"
/>
<div>
<button>
[Circular]
</button>
</div>
</body>
</html>,
"_index": undefined,
"_lastModTime": 1,
"_listeners": Object {
"DOMContentLoaded": Array [
Object {
"capture": false,
"f": [Function],
"listener": [Function],
},
],
"click": Array [
Object {
"capture": false,
"f": [Function],
"listener": [Function],
},
],
},
"_nextSibling": [Circular],
"_nextnid": 9,
"_nid": 1,
"_nodeIterators": null,
"_nodes": Array [
null,
[Circular],
<html>
<head />
<body>
<div
id="root"
/>
<div>
<button>
[Circular]
</button>
</div>
</body>
</html>,
<head />,
<body>
<div
id="root"
/>
<div>
<button>
[Circular]
</button>
</div>
</body>,
<div
id="root"
/>,
<div>
<button>
[Circular]
</button>
</div>,
<button>
[Circular]
</button>,
[Circular],
],
"_previousSibling": [Circular],
"_quirks": true,
"_scripting_enabled": true,
"_templateDocCache": null,
"byId": Object {
"root": <div
id="root"
/>,
},
"defaultView": [Object],
"doctype": null,
"documentElement": <html>
<head />
<body>
<div
id="root"
/>
<div>
<button>
[Circular]
</button>
</div>
</body>
</html>,
"implementation": Object {
"contextObject": [Circular],
},
"isHTML": true,
"modclock": 4,
"nodeType": 9,
"ownerDocument": null,
"parentNode": null,
"readyState": "loading",
},
"parentNode": <button>
[Circular]
</button>,
}
</button>
</div>
</body>

Related

How to disactivate the last breadcrumb in InertiaJS?

I am trying to disactivate the last crumb in InertiaJS (Laravel + Vue3) but I think I have an error or something missing somewhere. The error I am getting is the "isLast" is not defined.
isLast: This method simply takes in an index of the crumb array and checks if that crumb is the last one in the list.
selected: This is a simple method that emits an event whenever a crumb is selected. The event is then caught by Example.vue…
Here is the code:
BreadCrumb.vue
<template>
<div>
<ol class="inline-flex items-center space-x-1 md:space-x-3">
<li
v-for="(crumb, ci) in crumbs"
:key="ci"
>
<div class="inline-flex items-center">
<icon name="arrow"/>
<Link :href="`/${crumb}`" as="button" type="button" :class="{ disabled: isLast(ci) }" #click="selected(crumb)" class="capitalize" >
{{ crumb }}
</Link>
</div>
</li>
</ol>
</div>
</template>
<script>
import { Link } from '#inertiajs/inertia-vue3'
import Icon from '#/Shared/Icon'
export default {
components: {
Icon,
Link,
},
props: {
crumbs: {
type: Array,
required: true,
},
},
methods: {
isLast(index) {
return index === this.crumbs.length - 1;
},
},
}
</script>
Example.vue
<template>
<div class="md:p-12 md:pt-1">
<breadcrumb class="flex pl-4 mb-12" :crumbs="crumbs" #selected="selected"></breadcrumb>
</div>
</template>
<script>
import Breadcrumb from '#/Shared/Breadcrumb'
export default {
components: {
Breadcrumb,
},
return {
crumbs: ['home','users', 'create'],
}
methods: {
selected(crumb) {
console.log(crumb);
},
},
}
</script>
I would recommend binding the disabled-attribute
<Link ... :disabled="isLast(ci)" >
👆

Vue.js 3 Uncaught (in promise) TypeError: Cannot convert undefined or null to object

So, I'm trying to fetch my laravel api and already run php artisan serve. After that the error came out and I'm looking to find solution here but I have no idea what's going on.
The error shown in the console:
Uncaught (in promise) TypeError: Cannot convert undefined or null to object
The API:
{
"message": "List trash and category order by time",
"data": [
{
"id": 1,
"trash_id": 1,
"category_id": 2,
"created_at": "2022-01-01T12:41:43.000000Z",
"updated_at": "2022-01-01T12:41:43.000000Z",
"garbage": {
"id": 1,
"name": "Buku",
"weight": 1,
"created_at": "2022-01-01T12:41:19.000000Z",
"updated_at": "2022-01-01T12:41:19.000000Z"
},
"categories": {
"id": 2,
"name": "Kertas",
"price": 1800
}
}]
}
Index.vue script:
<script>
import axios from "axios";
import { onMounted, ref } from "vue";
export default {
setup() {
// reactive state
let all_trash = ref([]);
onMounted(() => {
// get data from api endpoint
axios
.get("http://127.0.0.1:8000/api/trash")
.then((result) => {
all_trash.value = result.data;
})
.catch((err) => {
console.log(err.response);
});
});
return {
all_trash,
};
},
};
</script>
Index.vue HTML:
<div v-for="(trash, index) in all_trash.data" :key="index">
<div class="card rounded shadow mb-3">
<div class="card-body">
<div class="mx-3">
<h5 class="mb-4">{{ trash.garbage.name }}</h5>
<p>
{{ trash.categories.name }}
<span class="float-end">
<button class="btn" style="color: red">Hapus</button>
</span>
</p>
</div>
</div>
</div>
</div>
Just add a condition that not to render the loop until data is not set. The data from API end point is not available on the initial dom rendered and there is not data in all_trash.data hence the error. Just add a v-if on top of the div and hopefully it should work.
<div v-if=" all_trash.data">
<div v-for="(trash, index) in all_trash.data" :key="index">
<div class="card rounded shadow mb-3">
<div class="card-body">
<div class="mx-3">
<h5 class="mb-4">{{ trash.garbage.name }}</h5>
<p>
{{ trash.categories.name }}
<span class="float-end">
<button class="btn" style="color: red">Hapus</button>
</span>
</p>
</div>
</div>
</div>
</div>

Kendo UI Grid passed data to another form

I had this demo that relate with my situation, how to bind an additional data in dataSource into my popup form. A popup form will appear if outletType = rest. Appreciate your helps.
DEMO IN DOJO
You do not need to set additional data, all dataSource's data will be available to be used in the modal, you don't need to show them in the grid.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.3.1017/styles/kendo.common.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.3.1017/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.3.1017/styles/kendo.default.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.3.1017/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/2018.3.1017/js/angular.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2018.3.1017/js/jszip.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2018.3.1017/js/kendo.all.min.js"></script>
</head>
<body>
<style>
#additionalVariables #lbl{width: 150px; display: inline-block; padding-bottom: 15px;
</style>
<div id="grid"></div>
<div id="additionalVariables" style="display:none">
<label id="lbl" for="capacity">Capacity</label>:
<input type="text" class="k-textbox" name="capacity" id="capacity" data-bind="value: selected.capacity" style="width:120px; text-align:center;">
<br>
<label id="lbl" for="roomservice">Room Service</label>:
<input class="k-radio" type="radio" name="roomservice" id="yes2" value="y" checked="checked"/>
<label class="k-radio-label" for="yes2" >Yes</label>
<input class="k-radio" type="radio" name="roomservice" id="no2" value="n" />
<label class="k-radio-label" for="no2" >No</label>
<br>
<label id="lbl" for="fastfood">Fast Food</label>:
<input class="k-radio" type="radio" name="fastfood" id="yes3" value="y" checked="checked"/>
<label class="k-radio-label" for="yes3" >Yes</label>
<input class="k-radio" type="radio" name="fastfood" id="no3" value="n" />
<label class="k-radio-label" for="no3" >No</label>
</div>
<script>
$(document).ready(function () {
var dataSource = [{
'capacity': '',
'roomservice': 'y',
'fastfood': 'y',
'outletType': 'retail',
'name': 'Data 1',
'additionalData': {
'a': 1
}
},
{
'capacity': 888,
'roomservice': 'n',
'fastfood': 'n',
'outletType': 'rest',
'name': 'Data 2',
'additionalData': {
'a': 2
}
},
{
'capacity': '',
'roomservice': 'y',
'fastfood': 'y',
'outletType': 'theme',
'name': 'Data 3',
'additionalData': {
'a': 3
}
},
{
'capacity': '1232',
'roomservice': 'y',
'fastfood': 'y',
'outletType': 'rest',
'name': 'Data 4',
'additionalData': {
'a': 4
}
},
];
grid = $('#grid').kendoGrid({
dataSource: dataSource,
editable: "inline",
toolbar: [{ name: "create", text: "Add" }],
columns: [
{ field: "outletType", title: "Outlet Type", width: 150, editor: outletType,
template: data => data.outletType == "rest" ? "Rest" : (data.outletType == "retail") ? "Retail" : (data.outletType == "spa") ? "Spa" : "Theme" },
{ field: "name", title: "name", width: 75 },
{ command: ["edit", "destroy"], title: " ", width: "250px" }
],
edit: openOutType
});
});
function openOutType(e){
if(e.model.outletType == 'rest'){
console.log(e.model.additionalData);
var additionalForm = $("#additionalVariables");
additionalForm.kendoWindow({
visible: false,
modal: true,
width: "350px",
height: "200px",
iframe: false,
resizable: false,
title: "Addtional Information"
});
additionalForm.data("kendoWindow").center().open();
}
}
function outletType(container, options) {
$('<input class="k-radio" id="radio1" name="outletType" type="radio" value="rest" >').appendTo(container);
$('<label class="k-radio-label" for="radio1">Rest </label>').appendTo(container);
$('<input class="k-radio" id="radio2" name="outletType" type="radio" value="spa" >').appendTo(container);
$('<label class="k-radio-label" for="radio2">Spa </label>').appendTo(container);
$('<input class="k-radio" id="radio3" name="outletType" type="radio" value="retail" >').appendTo(container);
$('<label class="k-radio-label" for="radio3">Retail </label>').appendTo(container);
$('<input class="k-radio" id="radio4" name="outletType" type="radio" value="theme" >').appendTo(container);
$('<label class="k-radio-label" for="radio4">Theme</label>').appendTo(container);
$('input:radio[name="outletType"]').change(function(){
if($(this).val() == 'rest'){
var additionalForm = $("#additionalVariables");
additionalForm.kendoWindow({
visible: false,
modal: true,
width: "350px",
height: "200px",
iframe: false,
resizable: false,
title: "Addtional Information"
});
additionalForm.data("kendoWindow").center().open();
}
});
}
</script>
</body>
</html>
Updated Dojo

RTL picker with dependent values

The reequirement is to make an RTL picker with multiple levels.
I copied the example from the documentation into a page equiped with the official frameworks' CSS for RTL users.
I have modified "textAlign" properties of each column as well.
For some reason the picker isn't acting as expected. open the snippet in full page mode.
var app = new Framework7({
root: '#app',
rtl: true,
theme: 'md'
});
app.views.create('#mainView', {
});
var carVendors = {
Japanese: ['Honda', 'Lexus', 'Mazda', 'Nissan', 'Toyota'],
German: ['Audi', 'BMW', 'Mercedes', 'Volkswagen', 'Volvo'],
American: ['Cadillac', 'Chrysler', 'Dodge', 'Ford']
};
var pickerDependent = app.picker.create({
inputEl: '#demo-picker-dependent',
rotateEffect: true,
formatValue: function(values) {
return values[1];
},
cols: [{
textAlign: 'right',
values: ['Japanese', 'German', 'American'],
onChange: function(picker, country) {
if (picker.cols[1].replaceValues) {
picker.cols[1].replaceValues(carVendors[country]);
}
}
},
{
textAlign: 'right',
values: carVendors.Japanese,
width: 160,
},
],
routableModals:false
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/framework7/2.3.0/css/framework7.rtl.md.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/framework7/2.3.0/js/framework7.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="block-title">
Dependent values</div>
<div id="app">
<div id="mainView">
<div class="list no-hairlines-md">
<ul>
<li>
<div class="item-content item-input">
<div class="item-inner">
<div class="item-input-wrap">
<input type="text" placeholder="Your car" readonly="readonly" id="demo-picker-dependent" />
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
That seems like a bug in Framework7.
CSS 'right' and 'left' properties for first and last '.picker-column' don't fit RTL layout (flipped). The attached repair solved it.
var app = new Framework7({
root: '#app',
rtl: true,
theme: 'md'
});
app.views.create('#mainView', {
});
var carVendors = {
Japanese: ['Honda', 'Lexus', 'Mazda', 'Nissan', 'Toyota'],
German: ['Audi', 'BMW', 'Mercedes', 'Volkswagen', 'Volvo'],
American: ['Cadillac', 'Chrysler', 'Dodge', 'Ford']
};
var pickerDependent = app.picker.create({
inputEl: '#demo-picker-dependent',
rotateEffect: true,
formatValue: function(values) {
return values[1];
},
cols: [{
textAlign: 'right',
values: ['Japanese', 'German', 'American'],
onChange: function(picker, country) {
if (picker.cols[1].replaceValues) {
picker.cols[1].replaceValues(carVendors[country]);
}
}
},
{
textAlign: 'right',
values: carVendors.Japanese,
width: 160,
},
],
routableModals:false
});
.picker-column.picker-column-first:after{
left:100% !important;
right:0 !important;
}
.picker-column.picker-column-last:after{
left:0 !important;
right:100% !important;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/framework7/2.3.0/css/framework7.rtl.md.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/framework7/2.3.0/js/framework7.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="block-title">
Dependent values</div>
<div id="app">
<div id="mainView">
<div class="list no-hairlines-md">
<ul>
<li>
<div class="item-content item-input">
<div class="item-inner">
<div class="item-input-wrap">
<input type="text" placeholder="Your car" readonly="readonly" id="demo-picker-dependent" />
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
EDIT:
github issue

How to attach onClick events to preview image in vue-dropzone-component

I have components dropzone on vue. Im install my template in settings.
Then i want to set v-on:click(method) to preview image in dropzone, but event don`t works. How to set correctly click to element?
<template>
<vue-dropzone :options="dropzoneOptions" ref="myVueDropzone" id="customdropzone"
:preview-template="template">
</vue-dropzone>
</template>
methods: {
template () {
return `<div class="dz-preview dz-file-preview" v-on:click.native="alert(1)">
<div class="dz-image" v-on:click="alert(1)">
<img data-dz-thumbnail>
</div>
<div class="dz-details" v-on:click="alert(1)">
<div class="dz-size"><span data-dz-size></span></div>
<div class="dz-filename"><span data-dz-name></span></div>
</div>
<div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div>
<div class="dz-error-message"><span data-dz-errormessage></span></div>
<div class="dz-success-mark"><i class="fa fa-check"></i></div>
<div class="dz-error-mark"><i class="fa fa-close"></i></div>
</div>`
;
},
}
data: function () {
return {
dropzoneOptions: {
url: 'https://httpbin.org/post',
thumbnailWidth: 200,
maxFilesize: 0.5,
addRemoveLinks: true,
previewTemplate: this.template(),
headers: {"My-Awesome-Header": "header value"},
},
salonID: 0,
photos: [],
}
},

Resources