I have a component that displays an image if the screen is desktop and it hides the image if the screen is for mobile devices:
<script>
export default {
name: 'MyComponentApp',
}
</script>
<template>
<div class="my-component">
<div class="my-component__image-container">
<img class="my-component__image-container--img" />
</div>
</div>
</template>
<style lang="scss" scoped>
.my-component {
&__image-container {
overflow: hidden;
width: 50%;
&--img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
}
@media (max-width: 600px) {
.my-component {
&__image-container {
&--img {
display: none;
}
}
}
}
</style>
When I try to do the unit test case and test if the image is hidden when the window.width
is below 600px
, it doesn't update the DOM and the image is still visible:
import MyComponentApp from './MyComponentApp.vue';
import { shallowMount } from '@vue/test-utils';
const factory = () => {
return shallowMount(MyComponentApp, {});
};
describe('DownloadApp.vue', () => {
let wrapper;
beforeEach(() => {
wrapper = factory();
});
describe('Check Items on Mobile Devices', () => {
it('Img on div.my-component__image-container shouldn\'t be displayed', async () => {
jest.spyOn(screen, 'height', 'get').mockReturnValue(500);
jest.spyOn(screen, 'width', 'get').mockReturnValue(500);
await wrapper.vm.$nextTick();
const image = wrapper.find('div.my-component__image-container > img');
expect(image.isVisible()).toBe(false);
});
});
});
However, the test fails:
DownloadApp.vue › Check Items on Mobile Devices › Img on div.my-component__image-container shouldn\'t be displayed
expect(received).toBe(expected) // Object.is equality
Expected: false
Received: true
Does anybody know how to update the DOM or make the test case realized that the screen width has changed and the image should be displayed?
CSS @media
queries depend on the viewport size, which currently cannot be manipulated from Jest alone, and setting window.innerWidth
in Jest won't have an effect in this case.
Alternatively, you could resize the viewport in Cypress tests. In a Vue CLI project, you could add the Cypress plugin by running this command from the root of your project:
vue add e2e-cypress
Then in <root>/tests/e2e/test.js
, insert the following tests that use cy.viewport()
to set the viewport size before checking the img
element's visibility:
describe('My img component', () => {
it('should show image for wide viewport', () => {
cy.visit('/') // navigate to page where test component exists
cy.viewport(800, 600)
cy.get('.my-component__image-container--img').should('be.visible')
})
it('should hide image for narrow viewport', () => {
cy.visit('/') // navigate to page where test component exists
cy.viewport(500, 600)
cy.get('.my-component__image-container--img').should('not.be.visible')
})
})