Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions core/websock.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,15 +258,6 @@ export default class Websock {
attach(rawChannel) {
this.init();

// Must get object and class methods to be compatible with the tests.
const channelProps = [...Object.keys(rawChannel), ...Object.getOwnPropertyNames(Object.getPrototypeOf(rawChannel))];
for (let i = 0; i < rawChannelProps.length; i++) {
const prop = rawChannelProps[i];
if (channelProps.indexOf(prop) < 0) {
throw new Error('Raw channel missing property: ' + prop);
}
}

this._websocket = rawChannel;
this._websocket.binaryType = "arraybuffer";
this._websocket.onmessage = this._recvMessage.bind(this);
Expand Down
92 changes: 0 additions & 92 deletions karma.conf.cjs

This file was deleted.

18 changes: 3 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"exports": "./core/rfb.js",
"scripts": {
"lint": "eslint app core po/po2js po/xgettext-html tests utils",
"test": "karma start karma.conf.cjs"
"test": "vitest run"
},
"repository": {
"type": "git",
Expand All @@ -34,29 +34,17 @@
"devDependencies": {
"@babel/core": "latest",
"@babel/preset-env": "latest",
"@vitest/browser-playwright": "^4.0.8",
"babel-plugin-import-redirect": "latest",
"browserify": "latest",
"chai": "latest",
"commander": "latest",
"eslint": "latest",
"fs-extra": "latest",
"globals": "latest",
"jsdom": "latest",
"karma": "latest",
"karma-mocha": "latest",
"karma-chrome-launcher": "latest",
"@chiragrupani/karma-chromium-edge-launcher": "latest",
"karma-firefox-launcher": "latest",
"karma-ie-launcher": "latest",
"karma-mocha-reporter": "latest",
"karma-safari-launcher": "latest",
"karma-script-launcher": "latest",
"mocha": "latest",
"pofile": "latest",
"sinon": "latest",
"sinon-chai": "latest"
"vitest": "^4.0.8"
},
"dependencies": {},
"keywords": [
"vnc",
"rfb",
Expand Down
9 changes: 1 addition & 8 deletions tests/assertions.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import * as chai from '../node_modules/chai/index.js';
import sinon from '../node_modules/sinon/pkg/sinon-esm.js';
import sinonChai from '../node_modules/sinon-chai/lib/sinon-chai.js';

window.expect = chai.expect;

window.sinon = sinon;
chai.use(sinonChai);
import { chai } from "vitest";

// noVNC specific assertions
chai.use(function (_chai, utils) {
Expand Down
1 change: 1 addition & 0 deletions tests/test.base64.js → tests/base64.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { describe, it, expect } from 'vitest';
import Base64 from '../core/base64.js';

describe('Base64 tools', function () {
Expand Down
30 changes: 17 additions & 13 deletions tests/test.browser.js → tests/browser.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
import { isMac, isWindows, isIOS, isAndroid, isChromeOS,
isSafari, isFirefox, isChrome, isChromium, isOpera, isEdge,
isGecko, isWebKit, isBlink,
Expand All @@ -7,52 +8,55 @@ describe('Async clipboard', function () {
"use strict";

beforeEach(function () {
sinon.stub(navigator, "clipboard").value({
writeText: sinon.stub(),
readText: sinon.stub(),
});
sinon.stub(navigator, "permissions").value({
query: sinon.stub().resolves({ state: "granted" })
vi.stubGlobal('navigator', {
...navigator,
clipboard: {
writeText: vi.fn(),
readText: vi.fn(),
},
permissions: {
query: vi.fn().mockResolvedValue({ state: "granted" })
}
});
});

afterEach(function () {
sinon.restore();
vi.restoreAllMocks();
});

it("queries permissions with correct parameters", async function () {
const queryStub = navigator.permissions.query;
await browserAsyncClipboardSupport();
expect(queryStub.firstCall).to.have.been.calledWithExactly({
expect(queryStub).toHaveBeenNthCalledWith(1, {
name: "clipboard-write",
allowWithoutGesture: true
});
expect(queryStub.secondCall).to.have.been.calledWithExactly({
expect(queryStub).toHaveBeenNthCalledWith(2, {
name: "clipboard-read",
allowWithoutGesture: false
});
});

it("is available when API present and permissions granted", async function () {
navigator.permissions.query.resolves({ state: "granted" });
navigator.permissions.query.mockResolvedValue({ state: "granted" });
const result = await browserAsyncClipboardSupport();
expect(result).to.equal('available');
});

it("is available when API present and permissions yield 'prompt'", async function () {
navigator.permissions.query.resolves({ state: "prompt" });
navigator.permissions.query.mockResolvedValue({ state: "prompt" });
const result = await browserAsyncClipboardSupport();
expect(result).to.equal('available');
});

it("is unavailable when permissions denied", async function () {
navigator.permissions.query.resolves({ state: "denied" });
navigator.permissions.query.mockResolvedValue({ state: "denied" });
const result = await browserAsyncClipboardSupport();
expect(result).to.equal('denied');
});

it("is unavailable when permissions API fails", async function () {
navigator.permissions.query.rejects(new Error("fail"));
navigator.permissions.query.mockRejectedValue(new Error("fail"));
const result = await browserAsyncClipboardSupport();
expect(result).to.equal('unsupported');
});
Expand Down
52 changes: 26 additions & 26 deletions tests/test.clipboard.js → tests/clipboard.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
import AsyncClipboard from '../core/clipboard.js';

describe('Async Clipboard', function () {
Expand All @@ -7,32 +8,31 @@ describe('Async Clipboard', function () {
let clipboard;

beforeEach(function () {
sinon.stub(navigator, "clipboard").value({
writeText: sinon.stub().resolves(),
readText: sinon.stub().resolves(),
});

sinon.stub(navigator, "permissions").value({
query: sinon.stub(),
vi.stubGlobal('navigator', {
...navigator,
clipboard: {
writeText: vi.fn().mockResolvedValue(),
readText: vi.fn().mockResolvedValue(),
},
permissions: {
query: vi.fn(),
}
});

targetMock = document.createElement("canvas");
clipboard = new AsyncClipboard(targetMock);
});

afterEach(function () {
sinon.restore();
vi.restoreAllMocks();
targetMock = null;
clipboard = null;
});

function stubClipboardPermissions(state) {
navigator.permissions.query
.withArgs({ name: 'clipboard-write', allowWithoutGesture: true })
.resolves({ state: state });
navigator.permissions.query
.withArgs({ name: 'clipboard-read', allowWithoutGesture: false })
.resolves({ state: state });
navigator.permissions.query.mockImplementation(args =>
Promise.resolve({ state: state })
);
}

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

const addListenerSpy = sinon.spy(targetMock, 'addEventListener');
const addListenerSpy = vi.spyOn(targetMock, 'addEventListener');
clipboard.grab();

await nextTick();

expect(addListenerSpy.calledWith('focus')).to.be.true;
expect(addListenerSpy).toHaveBeenCalledWith('focus', expect.any(Function));
});

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

const addListenerSpy = sinon.spy(targetMock, 'addEventListener');
const addListenerSpy = vi.spyOn(targetMock, 'addEventListener');
clipboard.grab();

await nextTick();

expect(addListenerSpy.calledWith('focus')).to.be.false;
expect(addListenerSpy).not.toHaveBeenCalledWith('focus', expect.any(Function));
});

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

const text = 'hello clipboard world';
navigator.clipboard.readText.resolves(text);
navigator.clipboard.readText.mockResolvedValue(text);

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

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

const text = 'should not read';
navigator.clipboard.readText.resolves(text);
navigator.clipboard.readText.mockResolvedValue(text);

clipboard.onpaste = sinon.spy();
clipboard.onpaste = vi.fn();

clipboard.grab();

await nextTick();

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

expect(clipboard.onpaste.called).to.be.false;
expect(clipboard.onpaste).not.toHaveBeenCalled();
});

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

expect(navigator.clipboard.writeText.calledWith(text)).to.be.true;
expect(result).to.be.true;
expect(navigator.clipboard.writeText).toHaveBeenCalledWith(text);
expect(result).toBe(true);
});

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

expect(navigator.clipboard.writeText.called).to.be.false;
expect(result).to.be.false;
expect(navigator.clipboard.writeText).not.toHaveBeenCalled();
expect(result).toBe(false);
});

});
5 changes: 3 additions & 2 deletions tests/test.copyrect.js → tests/copyrect.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { describe, it, expect, beforeAll, afterAll, beforeEach } from 'vitest';
import Websock from '../core/websock.js';
import Display from '../core/display.js';

Expand Down Expand Up @@ -33,8 +34,8 @@ describe('CopyRect decoder', function () {
let decoder;
let display;

before(FakeWebSocket.replace);
after(FakeWebSocket.restore);
beforeAll(FakeWebSocket.replace);
afterAll(FakeWebSocket.restore);

beforeEach(function () {
decoder = new CopyRectDecoder();
Expand Down
1 change: 1 addition & 0 deletions tests/test.deflator.js → tests/deflator.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { describe, it, expect } from 'vitest';
import { inflateInit, inflate } from "../vendor/pako/lib/zlib/inflate.js";
import ZStream from "../vendor/pako/lib/zlib/zstream.js";
import Deflator from "../core/deflator.js";
Expand Down
Loading