Skip to content

Commit e0326c8

Browse files
committed
feat(tests): move from karma to vite
1 parent d44f7e0 commit e0326c8

31 files changed

+2927
-2858
lines changed

core/websock.js

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -258,15 +258,6 @@ export default class Websock {
258258
attach(rawChannel) {
259259
this.init();
260260

261-
// Must get object and class methods to be compatible with the tests.
262-
const channelProps = [...Object.keys(rawChannel), ...Object.getOwnPropertyNames(Object.getPrototypeOf(rawChannel))];
263-
for (let i = 0; i < rawChannelProps.length; i++) {
264-
const prop = rawChannelProps[i];
265-
if (channelProps.indexOf(prop) < 0) {
266-
throw new Error('Raw channel missing property: ' + prop);
267-
}
268-
}
269-
270261
this._websocket = rawChannel;
271262
this._websocket.binaryType = "arraybuffer";
272263
this._websocket.onmessage = this._recvMessage.bind(this);

karma.conf.cjs

Lines changed: 0 additions & 92 deletions
This file was deleted.

package.json

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"exports": "./core/rfb.js",
1616
"scripts": {
1717
"lint": "eslint app core po/po2js po/xgettext-html tests utils",
18-
"test": "karma start karma.conf.cjs"
18+
"test": "vitest run"
1919
},
2020
"repository": {
2121
"type": "git",
@@ -34,29 +34,17 @@
3434
"devDependencies": {
3535
"@babel/core": "latest",
3636
"@babel/preset-env": "latest",
37+
"@vitest/browser-playwright": "^4.0.8",
3738
"babel-plugin-import-redirect": "latest",
3839
"browserify": "latest",
39-
"chai": "latest",
4040
"commander": "latest",
4141
"eslint": "latest",
4242
"fs-extra": "latest",
4343
"globals": "latest",
4444
"jsdom": "latest",
45-
"karma": "latest",
46-
"karma-mocha": "latest",
47-
"karma-chrome-launcher": "latest",
48-
"@chiragrupani/karma-chromium-edge-launcher": "latest",
49-
"karma-firefox-launcher": "latest",
50-
"karma-ie-launcher": "latest",
51-
"karma-mocha-reporter": "latest",
52-
"karma-safari-launcher": "latest",
53-
"karma-script-launcher": "latest",
54-
"mocha": "latest",
5545
"pofile": "latest",
56-
"sinon": "latest",
57-
"sinon-chai": "latest"
46+
"vitest": "^4.0.8"
5847
},
59-
"dependencies": {},
6048
"keywords": [
6149
"vnc",
6250
"rfb",

tests/assertions.js

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,4 @@
1-
import * as chai from '../node_modules/chai/index.js';
2-
import sinon from '../node_modules/sinon/pkg/sinon-esm.js';
3-
import sinonChai from '../node_modules/sinon-chai/lib/sinon-chai.js';
4-
5-
window.expect = chai.expect;
6-
7-
window.sinon = sinon;
8-
chai.use(sinonChai);
1+
import { chai } from "vitest";
92

103
// noVNC specific assertions
114
chai.use(function (_chai, utils) {

tests/test.base64.js renamed to tests/base64.test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { describe, it, expect } from 'vitest';
12
import Base64 from '../core/base64.js';
23

34
describe('Base64 tools', function () {

tests/test.browser.js renamed to tests/browser.test.js

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
12
import { isMac, isWindows, isIOS, isAndroid, isChromeOS,
23
isSafari, isFirefox, isChrome, isChromium, isOpera, isEdge,
34
isGecko, isWebKit, isBlink,
@@ -7,52 +8,55 @@ describe('Async clipboard', function () {
78
"use strict";
89

910
beforeEach(function () {
10-
sinon.stub(navigator, "clipboard").value({
11-
writeText: sinon.stub(),
12-
readText: sinon.stub(),
13-
});
14-
sinon.stub(navigator, "permissions").value({
15-
query: sinon.stub().resolves({ state: "granted" })
11+
vi.stubGlobal('navigator', {
12+
...navigator,
13+
clipboard: {
14+
writeText: vi.fn(),
15+
readText: vi.fn(),
16+
},
17+
permissions: {
18+
query: vi.fn().mockResolvedValue({ state: "granted" })
19+
}
1620
});
1721
});
1822

1923
afterEach(function () {
20-
sinon.restore();
24+
vi.restoreAllMocks();
2125
});
2226

2327
it("queries permissions with correct parameters", async function () {
2428
const queryStub = navigator.permissions.query;
2529
await browserAsyncClipboardSupport();
26-
expect(queryStub.firstCall).to.have.been.calledWithExactly({
30+
expect(queryStub).toHaveBeenNthCalledWith(1, {
2731
name: "clipboard-write",
2832
allowWithoutGesture: true
2933
});
30-
expect(queryStub.secondCall).to.have.been.calledWithExactly({
34+
expect(queryStub).toHaveBeenNthCalledWith(2, {
3135
name: "clipboard-read",
3236
allowWithoutGesture: false
3337
});
3438
});
3539

3640
it("is available when API present and permissions granted", async function () {
37-
navigator.permissions.query.resolves({ state: "granted" });
41+
navigator.permissions.query.mockResolvedValue({ state: "granted" });
3842
const result = await browserAsyncClipboardSupport();
3943
expect(result).to.equal('available');
4044
});
4145

4246
it("is available when API present and permissions yield 'prompt'", async function () {
43-
navigator.permissions.query.resolves({ state: "prompt" });
47+
navigator.permissions.query.mockResolvedValue({ state: "prompt" });
4448
const result = await browserAsyncClipboardSupport();
4549
expect(result).to.equal('available');
4650
});
4751

4852
it("is unavailable when permissions denied", async function () {
49-
navigator.permissions.query.resolves({ state: "denied" });
53+
navigator.permissions.query.mockResolvedValue({ state: "denied" });
5054
const result = await browserAsyncClipboardSupport();
5155
expect(result).to.equal('denied');
5256
});
5357

5458
it("is unavailable when permissions API fails", async function () {
55-
navigator.permissions.query.rejects(new Error("fail"));
59+
navigator.permissions.query.mockRejectedValue(new Error("fail"));
5660
const result = await browserAsyncClipboardSupport();
5761
expect(result).to.equal('unsupported');
5862
});
Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
12
import AsyncClipboard from '../core/clipboard.js';
23

34
describe('Async Clipboard', function () {
@@ -7,32 +8,31 @@ describe('Async Clipboard', function () {
78
let clipboard;
89

910
beforeEach(function () {
10-
sinon.stub(navigator, "clipboard").value({
11-
writeText: sinon.stub().resolves(),
12-
readText: sinon.stub().resolves(),
13-
});
14-
15-
sinon.stub(navigator, "permissions").value({
16-
query: sinon.stub(),
11+
vi.stubGlobal('navigator', {
12+
...navigator,
13+
clipboard: {
14+
writeText: vi.fn().mockResolvedValue(),
15+
readText: vi.fn().mockResolvedValue(),
16+
},
17+
permissions: {
18+
query: vi.fn(),
19+
}
1720
});
1821

1922
targetMock = document.createElement("canvas");
2023
clipboard = new AsyncClipboard(targetMock);
2124
});
2225

2326
afterEach(function () {
24-
sinon.restore();
27+
vi.restoreAllMocks();
2528
targetMock = null;
2629
clipboard = null;
2730
});
2831

2932
function stubClipboardPermissions(state) {
30-
navigator.permissions.query
31-
.withArgs({ name: 'clipboard-write', allowWithoutGesture: true })
32-
.resolves({ state: state });
33-
navigator.permissions.query
34-
.withArgs({ name: 'clipboard-read', allowWithoutGesture: false })
35-
.resolves({ state: state });
33+
navigator.permissions.query.mockImplementation(args =>
34+
Promise.resolve({ state: state })
35+
);
3636
}
3737

3838
function nextTick() {
@@ -42,30 +42,30 @@ describe('Async Clipboard', function () {
4242
it('grab() adds listener if permissions granted', async function () {
4343
stubClipboardPermissions('granted');
4444

45-
const addListenerSpy = sinon.spy(targetMock, 'addEventListener');
45+
const addListenerSpy = vi.spyOn(targetMock, 'addEventListener');
4646
clipboard.grab();
4747

4848
await nextTick();
4949

50-
expect(addListenerSpy.calledWith('focus')).to.be.true;
50+
expect(addListenerSpy).toHaveBeenCalledWith('focus', expect.any(Function));
5151
});
5252

5353
it('grab() does not add listener if permissions denied', async function () {
5454
stubClipboardPermissions('denied');
5555

56-
const addListenerSpy = sinon.spy(targetMock, 'addEventListener');
56+
const addListenerSpy = vi.spyOn(targetMock, 'addEventListener');
5757
clipboard.grab();
5858

5959
await nextTick();
6060

61-
expect(addListenerSpy.calledWith('focus')).to.be.false;
61+
expect(addListenerSpy).not.toHaveBeenCalledWith('focus', expect.any(Function));
6262
});
6363

6464
it('focus event triggers onpaste() if permissions granted', async function () {
6565
stubClipboardPermissions('granted');
6666

6767
const text = 'hello clipboard world';
68-
navigator.clipboard.readText.resolves(text);
68+
navigator.clipboard.readText.mockResolvedValue(text);
6969

7070
const spyPromise = new Promise(resolve => clipboard.onpaste = resolve);
7171

@@ -83,17 +83,17 @@ describe('Async Clipboard', function () {
8383
stubClipboardPermissions('denied');
8484

8585
const text = 'should not read';
86-
navigator.clipboard.readText.resolves(text);
86+
navigator.clipboard.readText.mockResolvedValue(text);
8787

88-
clipboard.onpaste = sinon.spy();
88+
clipboard.onpaste = vi.fn();
8989

9090
clipboard.grab();
9191

9292
await nextTick();
9393

9494
targetMock.dispatchEvent(new Event('focus'));
9595

96-
expect(clipboard.onpaste.called).to.be.false;
96+
expect(clipboard.onpaste).not.toHaveBeenCalled();
9797
});
9898

9999
it('writeClipboard() calls navigator.clipboard.writeText() if permissions granted', async function () {
@@ -103,8 +103,8 @@ describe('Async Clipboard', function () {
103103
const text = 'writing to clipboard';
104104
const result = clipboard.writeClipboard(text);
105105

106-
expect(navigator.clipboard.writeText.calledWith(text)).to.be.true;
107-
expect(result).to.be.true;
106+
expect(navigator.clipboard.writeText).toHaveBeenCalledWith(text);
107+
expect(result).toBe(true);
108108
});
109109

110110
it('writeClipboard() does not call navigator.clipboard.writeText() if permissions denied', async function () {
@@ -114,8 +114,8 @@ describe('Async Clipboard', function () {
114114
const text = 'should not write';
115115
const result = clipboard.writeClipboard(text);
116116

117-
expect(navigator.clipboard.writeText.called).to.be.false;
118-
expect(result).to.be.false;
117+
expect(navigator.clipboard.writeText).not.toHaveBeenCalled();
118+
expect(result).toBe(false);
119119
});
120120

121121
});

tests/test.copyrect.js renamed to tests/copyrect.test.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { describe, it, expect, beforeAll, afterAll, beforeEach } from 'vitest';
12
import Websock from '../core/websock.js';
23
import Display from '../core/display.js';
34

@@ -33,8 +34,8 @@ describe('CopyRect decoder', function () {
3334
let decoder;
3435
let display;
3536

36-
before(FakeWebSocket.replace);
37-
after(FakeWebSocket.restore);
37+
beforeAll(FakeWebSocket.replace);
38+
afterAll(FakeWebSocket.restore);
3839

3940
beforeEach(function () {
4041
decoder = new CopyRectDecoder();

tests/test.deflator.js renamed to tests/deflator.test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { describe, it, expect } from 'vitest';
12
import { inflateInit, inflate } from "../vendor/pako/lib/zlib/inflate.js";
23
import ZStream from "../vendor/pako/lib/zlib/zstream.js";
34
import Deflator from "../core/deflator.js";

0 commit comments

Comments
 (0)