primefaces / primevue

Next Generation Vue UI Component Library
https://primevue.org
MIT License
10.05k stars 1.2k forks source link

Dialog: Jest test teleport-stub is empty #3207

Closed arnyee closed 1 year ago

arnyee commented 1 year ago

Describe the bug

Hi, I really liked this project, and you always helped me I hope you can help me now too.

For one of my project I run jest tests, and after I upgrade primevue from 3.16.2 to 3.18.1 all of my test where I use Dialog component is failed at the point when I click to a button to show the the Dialog and I want to get The Dialog. In the error messages I see the teleport-stub tag of the Dialog is empty. I didn't find a breaking change in the normal Dialog module.

let button = wrapper.get('#open-dialog'); await button.trigger('click'); let dialog = await wrapper.get('#dialog');

And after that I get the error: Unable to get #dialog within:

<div class="card">
   <div class="p-col-12 p-md-12 p-lg-6 block-container">
     <div class="logo-container p-col-12"><button class="p-button p-component p-button-rounded p-button-primary p-mr-2" type="button" id="open-edit-company-dialog" role="button"><span class="pi pi-pencil p-button-icon p-button-
icon-left"></span> Edit</button></div>
        </div>
      </div>
    </div>
    <teleport-stub to="body"></teleport-stub>

My package.json: { "devDependencies": { "@babel/core": "^7.0.0", "@babel/plugin-proposal-object-rest-spread": "^7.15.6", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-transform-runtime": "^7.15.8", "@babel/preset-env": "^7.15.8", "@babel/preset-typescript": "^7.18.6", "@testing-library/vue": "^6.4.2", "@vue/compiler-sfc": "^3.0.11", "@vue/test-utils": "^2.0.0-rc.18", "@vue/vue3-jest": "29.2.0", "axios": "^0.21.1", "babel-core": "^7.0.0-bridge.0", "babel-jest": "^29.2.2", "babel-loader": "^8.2.2", "babel-plugin-add-module-exports": "^1.0.4", "babel-plugin-transform-require-context": "^0.1.1", "bootstrap": "^4.6.0", "cross-env": "^5.2.1", "jest": "^29.2.2", "jest-environment-jsdom": "^29.2.2", "jest-transform-stub": "^2.0.0", "jquery": "^3.6.0", "laravel-mix": "^6.0.16", "lodash": "^4.17.21", "popper.js": "^1.16.1", "postcss": "^8.2.10", "resolve-url-loader": "^3.1.2", "sass": "^1.32.8", "sass-loader": "^11.0.1", "string.prototype.replaceall": "^1.0.6", "vue": "^3.2.41", "vue-loader": "^16.2.0", "webpack": "^5.33.2" }, "dependencies": { "@fullcalendar/core": "^5.9.0", "@fullcalendar/daygrid": "^5.9.0", "@fullcalendar/interaction": "^5.9.0", "@fullcalendar/list": "^5.9.0", "@fullcalendar/timegrid": "^5.9.0", "@fullcalendar/vue3": "^5.9.0", "@mdi/font": "^2.8.94", "@polymer/font-roboto": "^3.0.2", "@popperjs/core": "^2.9.2", "@vue/cli-plugin-unit-jest": "^5.0.8", "bootstrap-vue": "^2.21.2", "browserslist": "^4.17.1", "canvg": "^3.0.8", "chart.js": "^3.9.1", "croppie": "^2.6.5", "exif-js": "^2.3.0", "font-awesome": "^4.7.0", "intl": "^1.2.5", "jest-canvas-mock": "^2.3.1", "jquery-touchswipe": "^1.6.19", "jspdf": "^2.4.0", "jspdf-autotable": "^3.5.23", "laravel-echo": "^1.10.0", "laravel-vue-lang": "^3.1.1", "mini-css-extract-plugin": "^1.4.1", "mixin-object": "^3.0.0", "moment": "^2.29.4", "node-sass": "^6.0.0", "npm": "^6.14.13", "nprogress": "^0.2.0", "pc-bootstrap4-datetimepicker": "^4.17.51", "primeflex": "^2.0.0", "primeicons": "^6.0.1", "primevue": "^3.5", "process": "^0.11.10", "pusher-js": "^4.4.0", "quill": "^1.3.7", "spectrum-colorpicker": "^1.8.1", "ts-jest": "^29.0.3", "v-viewer": "^3.0.10", "vue-axios": "^3.5.1", "vue-cropperjs": "^5.0.0", "vue-router": "^4.0.12", "vuedraggable": "^4.0.1", "xlsx": "^0.17.4" } }

Reproducer

No response

PrimeVue version

3.18.1

Vue version

3.2.41

Language

ALL

Build / Runtime

Vue CLI App

Browser(s)

No response

Steps to reproduce the behavior

I don"t know how to reproduce it, If you need any more information, please just ask! I've been stuck for a while and I just don't see the solution, I hope you can help me with this.

Expected behavior

It would be nice if it could work as in the older versions.

tugcekucukoglu commented 1 year ago

Dialog uses the Teleport and to ignore teleport you need to add teleport the options. For more information:

https://test-utils.vuejs.org/guide/advanced/teleport.html

arnyee commented 1 year ago

Thx for the quick response.

I know Dialog uses Teleport and it was very good before because I could test my Component completly, even so I have a form in a Dialog. But now the teleport stub is always empty when it need to load a Dialog.

<teleport-stub to="body"></teleport-stub>

Any other PrimeVue component which also uses Teleport like ConfirmPopup or Toast is work perfectly, only Dialog not work well. I hope you can help me to fix this!

parryma-admin-cloud commented 1 year ago

I'm having the same issue as well.

tugcekucukoglu commented 1 year ago

Can not catch the problem. Did you import your global like this:

global: {
     stubs: {
          teleport: true
      }
},
arnyee commented 1 year ago

@tugcekucukoglu Yes it is on: and it works well for every PrimeVue component except Dialog. Only for Dialog it give back an empty teleport-stub, but for another Components like Toast which also uses teleport is still works fine

tugcekucukoglu commented 1 year ago

Could you check these examples? https://github.com/primefaces/primevue/blob/master/src/components/dialog/Dialog.spec.js

github-actions[bot] commented 1 year ago

We're unable to replicate your issue, if you are able to create a reproducer or add details please edit this issue. This issue will be closed if no activities in 20 days.

arnyee commented 1 year ago

@tugcekucukoglu

This is one of my test:

` import {mount, flushPromises} from '@vue/test-utils'; import { nextTick } from 'vue'; import OrderChangeDeliveryStatus from './OrderChangeDeliveryStatus.vue'; import OrderService from "./OrderService";

it('Change order delivery status with inner courier', async () => { let orderService = new OrderService(); const wrapper = mount(OrderChangeDeliveryStatus, openOrder); const spy = jest.spyOn(orderService, 'setDeliveryStatus'); const spyDialog = jest.spyOn(orderService, 'getDeliveryCourierDialogData'); await flushPromises(); expect(wrapper.text()).toContain('Deliverable to technician'); await nextTick(); let openStatusChangerButton = wrapper.get("#open-change-delivery-status-1"); await openStatusChangerButton.trigger('click'); await wrapper.get('#change-delivery-status-delivering-to-technician'); let statusChangeButton = wrapper.get('#change-delivery-status-delivering-to-technician'); await statusChangeButton.trigger('click'); await wrapper.get('#changeCourierDialog'); await wrapper.get('#courier-option-1').trigger('click'); await wrapper.get('#submit-courier-dialog'); let submitCourierDialog = wrapper.get('#submit-courier-dialog'); await submitCourierDialog.trigger('click'); await nextTick(); let data = { "delivery_status": 'delivering-to-technician', "courier": 1, "other_courier": null, }; expect(spy).toBeCalledTimes(1); expect(spyDialog).toBeCalledTimes(1); expect(spy).toHaveBeenCalledWith(openOrder.propsData.order.id, data, openOrder.propsData.isShow); });`

arnyee commented 1 year ago

And this is an error message for this I thought I give you the most importatn parts of it but i give the full to you:

FAIL resources/js/components/order/OrderChangeDeliveryStatus.spec.js (5.508 s) ● OrderChangeDeliveryStatus › Change order delivery status with inner courier Unable to get #changeCourierDialog within:

<teleport-stub to="body">
     <div class="p-toast p-component p-toast-top-right p-ripple-disabled">
        <div></div>
      </div>
    </teleport-stub>
    <div>
      <div>
        <div><button class="p-button p-component p-button-text" type="button" aria-label="Deliverable to technician" id="open-change-delivery-status-1">
            <!----><span class="pi pi-angle-down p-button-icon p-button-icon-right"></span><span class="p-button-label">Deliverable to technician</span>
            <!---->
          </button></div>
      </div>
    </div>
    <teleport-stub to="body">
      <div class="p-overlaypanel p-component p-ripple-disabled p-overlaypanel-enter-from p-overlaypanel-enter-active" style="width: 250px; visibility: visible; display: none; transform-origin: top; top: 0px; left: 0px; --overlayArro
wLeft: 0px; z-index: 3103;" pv_id_3="">
        <div class="p-overlaypanel-content">
          <div><button class="p-button p-component p-button-text" type="button" aria-label="Fogorvoshoz szállítható" id="change-delivery-status-deliverable-to-dentist" style="width: 100%;">
              <!---->
              <!----><span class="p-button-label">Fogorvoshoz szállítható</span>
              <!---->
            </button></div>
          <div><button class="p-button p-component p-button-text" type="button" aria-label="Fogorvosnál" id="change-delivery-status-delivered-to-dentist" style="width: 100%;">
              <!---->
              <!----><span class="p-button-label">Fogorvosnál</span>
              <!---->
            </button></div>
          <div><button class="p-button p-component p-button-text" type="button" aria-label="Technikusnál" id="change-delivery-status-delivered-to-technician" style="width: 100%;">
              <!---->
              <!----><span class="p-button-label">Technikusnál</span>
              <!---->
            </button></div>
          <div><button class="p-button p-component p-button-text" type="button" aria-label="Fogorvoshoz szállítás alatt" id="change-delivery-status-delivering-to-dentist" style="width: 100%;">
              <!---->
              <!----><span class="p-button-label">Fogorvoshoz szállítás alatt</span>
              <!---->
            </button></div>
          <div><button class="p-button p-component p-button-text" type="button" aria-label="Technikushoz szállítás alatt" id="change-delivery-status-delivering-to-technician" style="width: 100%;">
              <!---->
              <!----><span class="p-button-label">Technikushoz szállítás alatt</span>
              <!---->
            </button></div>
        </div>
        <!---->
      </div>
    </teleport-stub>
    <teleport-stub to="body"></teleport-stub>
  67|         await statusChangeButton.trigger('click');
> 68 |         await wrapper.get('#changeCourierDialog');
     |                       ^
  69 |         await wrapper.get('#courier-option-1').trigger('click');
  70 |         await wrapper.get('#submit-courier-dialog');
  71 |         let submitCourierDialog = wrapper.get('#submit-courier-dialog');

  at VueWrapper.Object.<anonymous>.BaseWrapper.get (node_modules/@vue/test-utils/dist/vue-test-utils.cjs.js:7189:15)
  at Object.get (resources/js/components/order/OrderChangeDeliveryStatus.spec.js:68:23)

`

arnyee commented 1 year ago

@tugcekucukoglu I hope this extra informations is enough, and you can see the problem, or if you need anything more please let me know it

arnyee commented 1 year ago

@tugcekucukoglu

now I see if the Dialog component visible is default false whent the container component is mounted, than after in my test I change it with a click event to true, than the teleport-stub not change in jest-test.

@parryma-admin-cloud You found any solution?

tugcekucukoglu commented 1 year ago

It's really hard to understand the logic of this code. But I have tested this https://github.com/primefaces/primevue/blob/master/src/components/dialog/Dialog.spec.js#L6 and it seems working.

arnyee commented 1 year ago

Sorry if it hard to understand.

But if you have a little more time, you can make an easier test , the main plot, for the component has a data variable show:false.

And in this component include a button and a Dialog component, if you click the Button the show change to true.

bahadirsofuoglu commented 1 year ago

Hi, please help me to understand. After teleporting the Dialog, it seems unlikely to me that it is called in the wrapper. Maybe you should check to the body. I don't know exactly what the case is. But you should stub all third part components because already been tested.

arnyee commented 1 year ago

hi @bahadirsofuoglu Thx for your response now I could handle my problem. There are jest and/or babel packages that break when updated no matter how I changed them. I was able to download the latest primevue with this package json and my tests are working again. Testing the dialog breaks for some reason.

Working package.json: { "devDependencies": { "@babel/core": "^7.0.0", "@babel/plugin-transform-runtime": "^7.15.8", "@babel/preset-env": "^7.15.8", "@babel/preset-typescript": "^7.18.6", "@testing-library/vue": "^6.4.2", "@vue/compiler-sfc": "^3.0.11", "@vue/test-utils": "^2.0.0-rc.18", "axios": "^0.21.1", "babel-core": "^7.0.0-bridge.0", "babel-jest": "^27.2.5", "babel-loader": "^8.2.2", "babel-plugin-add-module-exports": "^1.0.4", "babel-plugin-transform-require-context": "^0.1.1", "bootstrap": "^4.6.0", "cross-env": "^5.2.1", "jest": "^27.2.5", "jest-transform-stub": "^2.0.0", "jquery": "^3.6.0", "laravel-mix": "^6.0.16", "lodash": "^4.17.21", "popper.js": "^1.16.1", "postcss": "^8.2.10", "resolve-url-loader": "^3.1.2", "sass": "^1.32.8", "sass-loader": "^11.0.1", "string.prototype.replaceall": "^1.0.6", "vue": "^3.2.20", "vue-loader": "^16.2.0", "vue3-jest": "^27.0.0-alpha.1", "webpack": "^5.33.2" }, "dependencies": { "@fullcalendar/core": "^5.9.0", "@fullcalendar/daygrid": "^5.9.0", "@fullcalendar/interaction": "^5.9.0", "@fullcalendar/list": "^5.9.0", "@fullcalendar/timegrid": "^5.9.0", "@fullcalendar/vue3": "^5.9.0", "@mdi/font": "^2.8.94", "@polymer/font-roboto": "^3.0.2", "@popperjs/core": "^2.9.2", "bootstrap-vue": "^2.21.2", "browserslist": "^4.17.1", "canvg": "^3.0.8", "chart.js": "^3.9.1", "croppie": "^2.6.5", "exif-js": "^2.3.0", "font-awesome": "^4.7.0", "intl": "^1.2.5", "jest-canvas-mock": "^2.3.1", "jquery-touchswipe": "^1.6.19", "jspdf": "^2.4.0", "jspdf-autotable": "^3.5.23", "laravel-echo": "^1.10.0", "laravel-vue-lang": "^3.1.1", "mini-css-extract-plugin": "^1.4.1", "mixin-object": "^3.0.0", "moment": "^2.24.0", "node-sass": "^6.0.0", "npm": "^6.14.13", "nprogress": "^0.2.0", "pc-bootstrap4-datetimepicker": "^4.17.51", "primeflex": "^2.0.0", "primeicons": "^6.0.1", "primevue": "^3.18.1", "process": "^0.11.10", "pusher-js": "^4.4.0", "quill": "^1.3.7", "spectrum-colorpicker": "^1.8.1", "ts-jest": "^28.0.7", "v-viewer": "^3.0.10", "vue-axios": "^3.2.4", "vue-cropperjs": "^5.0.0", "vue-router": "^4.0.12", "vuedraggable": "^4.0.1", "xlsx": "^0.17.4" } }

arnyee commented 1 year ago

@bahadirsofuoglu I think that would be nice if someone can check the difference between the 2 package.json and check which upgrade kill A Dialog test in a Custom Component, I hope I was able to help in mapping this error and that there will be a solution for it as soon as possible!