diff --git a/src/components/blockui/BlockUI.spec.js b/src/components/blockui/BlockUI.spec.js
new file mode 100644
index 000000000..0717de401
--- /dev/null
+++ b/src/components/blockui/BlockUI.spec.js
@@ -0,0 +1,63 @@
+import { config, mount } from '@vue/test-utils';
+import BlockUI from './BlockUI.vue';
+import Panel from '@/components/panel/Panel.vue';
+import Button from '@/components/button/Button.vue';
+
+config.global.mocks = {
+ $primevue: {
+ config: {
+ zIndex: {
+ modal: 1100
+ }
+ }
+ }
+}
+
+describe('BlockUI.vue', () => {
+ it('should blocked and unblocked the panel', async () => {
+ const wrapper = mount({
+ template: `
+
+
+
+
+
+ The story begins as Don Vito Corleone, the head of a New York Mafia family.
+
+
+ `,
+ components: {
+ BlockUI,
+ Panel,
+ Button
+ },
+ data() {
+ return {
+ blockedPanel: false
+ }
+ },
+ methods: {
+ blockPanel() {
+ this.blockedPanel = true;
+ },
+ unblockPanel() {
+ this.blockedPanel = false;
+ }
+ }
+ });
+
+ expect(wrapper.find('.p-blockui-container').exists()).toBe(true);
+
+ const buttons = wrapper.findAll('.p-button');
+
+ await buttons[0].trigger('click');
+
+ expect(wrapper.find('.p-blockui').exists()).toBe(true);
+ expect(wrapper.find('.p-blockui').classes()).toContain('p-component-overlay-enter');
+ expect(wrapper.find('.p-blockui').attributes().style).toEqual('z-index: 1101;');
+
+ await buttons[1].trigger('click');
+
+ expect(wrapper.find('.p-blockui').classes()).toContain('p-component-overlay-leave');
+ });
+});
diff --git a/src/components/ripple/Ripple.spec.js b/src/components/ripple/Ripple.spec.js
new file mode 100644
index 000000000..f3a9b220a
--- /dev/null
+++ b/src/components/ripple/Ripple.spec.js
@@ -0,0 +1,32 @@
+import { config, mount } from '@vue/test-utils';
+import Ripple from './Ripple';
+
+config.global.mocks = {
+ $primevue: {
+ config: {
+ ripple: true
+ }
+ }
+}
+
+config.global.directives = {
+ Ripple
+}
+
+describe('Ripple', () => {
+ it('should exist', async () => {
+ const wrapper = mount({
+ template: `
+
Default
+ `
+ });
+
+ const card = wrapper.find('.card');
+
+ expect(wrapper.find('.p-ink').exists()).toBe(true);
+
+ await card.trigger('mousedown');
+
+ expect(wrapper.find('.p-ink').classes()).toContain('p-ink-active');
+ });
+});
\ No newline at end of file
diff --git a/src/components/styleclass/StyleClass.spec.js b/src/components/styleclass/StyleClass.spec.js
new file mode 100644
index 000000000..821c9abe8
--- /dev/null
+++ b/src/components/styleclass/StyleClass.spec.js
@@ -0,0 +1,36 @@
+import { config, mount } from '@vue/test-utils';
+import StyleClass from './StyleClass';
+import Button from '@/components/button/Button.vue';
+import InputText from '@/components/inputtext/InputText.vue';
+
+config.global.directives = {
+ 'styleclass': StyleClass
+}
+
+describe('StyleClass', () => {
+ it('should work with next selector', async () => {
+ const wrapper = mount({
+ template: `
+
+
+ `,
+ components: {
+ Button,
+ InputText
+ }
+ });
+
+ const button = wrapper.find('.p-button');
+ const input = wrapper.find('.p-inputtext');
+
+ expect(input.classes()).not.toContain('p-disabled');
+
+ await button.trigger('click');
+
+ expect(input.classes()).toContain('p-disabled');
+
+ await button.trigger('click');
+
+ expect(input.classes()).not.toContain('p-disabled');
+ });
+});
\ No newline at end of file
diff --git a/src/components/terminal/Terminal.spec.js b/src/components/terminal/Terminal.spec.js
new file mode 100644
index 000000000..7d2de4114
--- /dev/null
+++ b/src/components/terminal/Terminal.spec.js
@@ -0,0 +1,97 @@
+import { mount } from '@vue/test-utils';
+import TerminalService from '@/components/terminalservice/TerminalService';
+import Terminal from './Terminal.vue';
+
+describe('Terminal.vue', () => {
+ it('should return valid command', async () => {
+ const wrapper = mount({
+ components: {
+ Terminal
+ },
+ template: ``,
+ mounted() {
+ TerminalService.on('command', this.commandHandler);
+ },
+ beforeUnmount() {
+ TerminalService.off('command', this.commandHandler);
+ },
+ methods: {
+ commandHandler(text) {
+ let response;
+ let argsIndex = text.indexOf(' ');
+ let command = argsIndex !== -1 ? text.substring(0, argsIndex) : text;
+
+ switch(command) {
+ case "d":
+ response = 'Valid command';
+ break;
+
+ default:
+ response = "Unknown command: " + command;
+ }
+
+ TerminalService.emit('response', response);
+ }
+ }
+ });
+
+ expect(wrapper.find('.p-terminal.p-component').exists()).toBe(true);
+ expect(wrapper.find('input.p-terminal-input').exists()).toBe(true);
+
+ wrapper.find('input.p-terminal-input').setValue('d');
+
+ wrapper.find('.p-terminal-input').trigger('keydown', {
+ keyCode: 13
+ });
+
+ await wrapper.vm.$nextTick();
+
+ expect(wrapper.find('.p-terminal-response').text()).toBe('Valid command');
+ });
+
+ it('should return invalid command', async () => {
+ const wrapper = mount({
+ components: {
+ Terminal
+ },
+ template: ``,
+ mounted() {
+ TerminalService.on('command', this.commandHandler);
+ },
+ beforeUnmount() {
+ TerminalService.off('command', this.commandHandler);
+ },
+ methods: {
+ commandHandler(text) {
+ let response;
+ let argsIndex = text.indexOf(' ');
+ let command = argsIndex !== -1 ? text.substring(0, argsIndex) : text;
+
+ switch(command) {
+ case "d":
+ response = 'Valid command';
+ break;
+
+ default:
+ response = "Unknown command: " + command;
+ }
+
+ TerminalService.emit('response', response);
+ }
+ }
+ });
+
+ expect(wrapper.find('.p-terminal.p-component').exists()).toBe(true);
+ expect(wrapper.find('input.p-terminal-input').exists()).toBe(true);
+
+ wrapper.find('input.p-terminal-input').setValue('dd');
+
+ wrapper.find('.p-terminal-input').trigger('keydown', {
+ keyCode: 13
+ });
+
+ await wrapper.vm.$nextTick();
+
+ expect(wrapper.find('.p-terminal-response').text()).toBe('Unknown command: dd');
+ });
+});
\ No newline at end of file