@interopio/iocd-cli 0.0.91 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.md +23 -0
- package/dist/commands/test.command.js +47 -0
- package/dist/commands/test.command.js.map +1 -1
- package/dist/services/template.service.js +15 -4
- package/dist/services/template.service.js.map +1 -1
- package/dist/services/test-infrastructure.service.js +113 -0
- package/dist/services/test-infrastructure.service.js.map +1 -0
- package/dist/templates/tests/.agents/skills/iocd-wdio-testing/SKILL.md +71 -0
- package/dist/templates/tests/.agents/skills/iocd-wdio-testing/references/authoring.md +243 -0
- package/dist/templates/tests/.agents/skills/iocd-wdio-testing/references/commands.md +24 -0
- package/dist/templates/tests/.agents/skills/iocd-wdio-testing/references/configuration.md +30 -0
- package/dist/templates/tests/.agents/skills/iocd-wdio-testing/references/models.md +52 -0
- package/dist/templates/tests/.agents/skills/iocd-wdio-testing/references/setup.md +62 -0
- package/dist/templates/tests/.agents/skills/iocd-wdio-testing/references/troubleshooting.md +66 -0
- package/dist/templates/tests/tests/README.md +79 -0
- package/dist/templates/tests/tests/config/system.json +36 -0
- package/dist/templates/tests/tests/package-lock.json +3425 -2274
- package/dist/templates/tests/tests/package.json +19 -11
- package/dist/templates/tests/tests/tests/assets/applications/channel-client/index.html +31 -0
- package/dist/templates/tests/tests/tests/assets/applications/interop-responder/index.html +25 -0
- package/dist/templates/tests/tests/tests/assets/applications/people-list/index.html +59 -0
- package/dist/templates/tests/tests/tests/assets/applications/person-details/index.html +26 -0
- package/dist/templates/tests/tests/tests/assets/applications/shared-context-client/index.html +37 -0
- package/dist/templates/tests/tests/tests/assets/applications/web/index.html +31 -0
- package/dist/templates/tests/tests/tests/assets/applications/workspace-widget/index.html +14 -0
- package/dist/templates/tests/tests/tests/channel-selector.spec.ts +80 -0
- package/dist/templates/tests/tests/tests/common/iocd.ts +125 -0
- package/dist/templates/tests/tests/tests/config/apps.json +96 -0
- package/dist/templates/tests/tests/tests/interop.spec.ts +37 -0
- package/dist/templates/tests/tests/tests/notifications.spec.ts +37 -0
- package/dist/templates/tests/tests/tests/shared-contexts.spec.ts +71 -0
- package/dist/templates/tests/tests/tests/single-app.spec.ts +39 -0
- package/dist/templates/tests/tests/tests/workspace-add-app.spec.ts +64 -0
- package/dist/templates/tests/tests/tests/workspace-interop.spec.ts +99 -0
- package/dist/templates/tests/tests/tsconfig.json +7 -5
- package/dist/templates/tests/tests/wdio.config.ts +29 -25
- package/package.json +4 -3
- package/dist/templates/tests/tests/tests/sample.spec.ts +0 -73
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { expect } from "chai";
|
|
2
|
+
import type { IOConnectDesktop } from "@interopio/desktop";
|
|
3
|
+
import { $, browser } from "@wdio/globals";
|
|
4
|
+
import { createCleanupRegistry, waitForEvent } from "./common/iocd";
|
|
5
|
+
|
|
6
|
+
// Starts two instances of the same client app, publishes a Shared Context update
|
|
7
|
+
// from one instance, and verifies that the other instance renders the update.
|
|
8
|
+
describe("Shared Contexts", () => {
|
|
9
|
+
const contextName = "IOCD.Sample.SelectedClient";
|
|
10
|
+
const clientName = "Ada Lovelace";
|
|
11
|
+
let instances: IOConnectDesktop.AppManager.Instance[] = [];
|
|
12
|
+
let cleanups = createCleanupRegistry();
|
|
13
|
+
|
|
14
|
+
beforeEach(async () => {
|
|
15
|
+
const io = await browser.io();
|
|
16
|
+
cleanups = createCleanupRegistry();
|
|
17
|
+
await io.contexts.destroy(contextName).catch(() => undefined);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
afterEach(async () => {
|
|
21
|
+
const io = await browser.io();
|
|
22
|
+
await cleanups.run();
|
|
23
|
+
await Promise.all(instances.map((instance) => instance.stop().catch(() => undefined)));
|
|
24
|
+
instances = [];
|
|
25
|
+
await io.contexts.destroy(contextName).catch(() => undefined);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("delivers an update from one app instance to another", async () => {
|
|
29
|
+
const io = await browser.io();
|
|
30
|
+
const app = io.appManager.application("shared-context-client")!;
|
|
31
|
+
|
|
32
|
+
const publisher = await app.start({}, { title: "Context Publisher" });
|
|
33
|
+
const subscriber = await app.start({}, { title: "Context Subscriber" });
|
|
34
|
+
instances = [publisher, subscriber];
|
|
35
|
+
|
|
36
|
+
const publisherWindow = await publisher.getWindow();
|
|
37
|
+
const subscriberWindow = await subscriber.getWindow();
|
|
38
|
+
|
|
39
|
+
// Wait until the receiving app has subscribed before publishing the update.
|
|
40
|
+
await browser.switchById(subscriberWindow.id);
|
|
41
|
+
await browser.waitUntil(async () => (await $("#context-status").getText()) === "Ready", {
|
|
42
|
+
timeoutMsg: "Expected the subscriber app to initialize its Shared Context subscription",
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const contextUpdate = await waitForEvent<{ clientName?: string }>(
|
|
46
|
+
(listener) =>
|
|
47
|
+
io.contexts.subscribe(contextName, (data) => {
|
|
48
|
+
listener(data as { clientName?: string });
|
|
49
|
+
}),
|
|
50
|
+
{
|
|
51
|
+
predicate: (data) => data.clientName === clientName,
|
|
52
|
+
timeoutMsg: `Expected the ${contextName} context to select ${clientName}`,
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
cleanups.add(contextUpdate.unsubscribe);
|
|
56
|
+
|
|
57
|
+
await browser.switchById(publisherWindow.id);
|
|
58
|
+
await $("#share-client").waitAndClick();
|
|
59
|
+
|
|
60
|
+
const receivedContext = await contextUpdate.result;
|
|
61
|
+
expect(receivedContext.clientName).to.equal(clientName);
|
|
62
|
+
|
|
63
|
+
await browser.switchById(subscriberWindow.id);
|
|
64
|
+
const selectedClient = await $("#selected-client");
|
|
65
|
+
await browser.waitUntil(async () => (await selectedClient.getText()) === clientName, {
|
|
66
|
+
timeoutMsg: `Expected the subscriber app to receive ${clientName}`,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
expect(await selectedClient.getText()).to.equal(clientName);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { expect } from "chai";
|
|
2
|
+
import type { IOConnectDesktop } from "@interopio/desktop";
|
|
3
|
+
import { $, browser } from "@wdio/globals";
|
|
4
|
+
|
|
5
|
+
// Starts a single app in io.Connect Desktop, drives its UI with WebdriverIO,
|
|
6
|
+
// and asserts the resulting state. This is the smallest end-to-end shape: the
|
|
7
|
+
// io.Connect API launches the app, then WebdriverIO interacts with and verifies
|
|
8
|
+
// its DOM.
|
|
9
|
+
describe("Single-app UI", () => {
|
|
10
|
+
let instance: IOConnectDesktop.AppManager.Instance | undefined;
|
|
11
|
+
|
|
12
|
+
afterEach(async () => {
|
|
13
|
+
// Stop the app even if the test failed, so the next test starts clean.
|
|
14
|
+
await instance?.stop().catch(() => undefined);
|
|
15
|
+
instance = undefined;
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("increments the counter when the button is pressed", async () => {
|
|
19
|
+
const io = await browser.io();
|
|
20
|
+
|
|
21
|
+
// Launch the registered "web" fixture app through the io.Connect API.
|
|
22
|
+
instance = await io.appManager.application("web")!.start();
|
|
23
|
+
const window = await instance.getWindow();
|
|
24
|
+
|
|
25
|
+
// Move the WebdriverIO context into the app window before touching its DOM.
|
|
26
|
+
await browser.switchById(window.id);
|
|
27
|
+
|
|
28
|
+
// Click the button (waitAndClick waits for it to be visible and clickable).
|
|
29
|
+
await $("#increment-counter").waitAndClick();
|
|
30
|
+
|
|
31
|
+
// Wait for the observable result instead of asserting immediately.
|
|
32
|
+
const counter = await $("#counter");
|
|
33
|
+
await browser.waitUntil(async () => (await counter.getText()) === "1", {
|
|
34
|
+
timeoutMsg: "Expected the counter to increment to 1",
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
expect(await counter.getText()).to.equal("1");
|
|
38
|
+
});
|
|
39
|
+
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { expect } from "chai";
|
|
2
|
+
import type { IOConnectWorkspaces } from "@interopio/workspaces-api";
|
|
3
|
+
import { $, browser } from "@wdio/globals";
|
|
4
|
+
|
|
5
|
+
// Adds an app to a Workspace by driving the Workspaces App UI with WebdriverIO
|
|
6
|
+
// clicks (the frame's add button and the add-application popup) instead of the
|
|
7
|
+
// workspace.addWindow() API. This relies on the test platform running in
|
|
8
|
+
// universal mode (config/system.json sets "advancedMode": false), where the
|
|
9
|
+
// popup renders inside the frame window rather than a separate popup window.
|
|
10
|
+
describe("Workspace add-app popup", function () {
|
|
11
|
+
this.timeout(60_000);
|
|
12
|
+
|
|
13
|
+
const addedAppName = "workspace-widget";
|
|
14
|
+
let workspace: IOConnectWorkspaces.Workspace | undefined;
|
|
15
|
+
|
|
16
|
+
afterEach(async () => {
|
|
17
|
+
// Close the workspace (and its windows) after each test.
|
|
18
|
+
await workspace?.close().catch(() => undefined);
|
|
19
|
+
workspace = undefined;
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("adds an app to a workspace through the add-application popup", async () => {
|
|
23
|
+
const io = await browser.io();
|
|
24
|
+
|
|
25
|
+
// Start from an empty workspace so the frame shows the empty-state add button.
|
|
26
|
+
workspace = await io.workspaces!.createWorkspace({ children: [] });
|
|
27
|
+
await browser.switchById(workspace.frameId);
|
|
28
|
+
|
|
29
|
+
// Open the add-application popup from the empty container's add button.
|
|
30
|
+
await $(".wsp-empty-container button.add-button").waitAndClick();
|
|
31
|
+
|
|
32
|
+
// Filter the popup's app list down to the target app by its title.
|
|
33
|
+
const search = await $(".add-application #appSearch");
|
|
34
|
+
await search.waitForDisplayed();
|
|
35
|
+
await search.setValue("Workspace Widget");
|
|
36
|
+
|
|
37
|
+
// Row markup differs between Workspaces App versions, so match either shape.
|
|
38
|
+
await $(
|
|
39
|
+
".add-application .applicationsList .list-group-item, .add-application li.io-list-item"
|
|
40
|
+
).waitAndClick();
|
|
41
|
+
|
|
42
|
+
// The click adds the app through the real UI; confirm via the Workspaces API.
|
|
43
|
+
await browser.waitUntil(
|
|
44
|
+
async () => {
|
|
45
|
+
const current = (await io.workspaces!.getAllWorkspaces()).find(
|
|
46
|
+
(candidate) => candidate.id === workspace!.id
|
|
47
|
+
);
|
|
48
|
+
return current?.getAllWindows().length === 1;
|
|
49
|
+
},
|
|
50
|
+
{ timeoutMsg: "Expected the added app to appear in the workspace" }
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
const current = (await io.workspaces!.getAllWorkspaces()).find(
|
|
54
|
+
(candidate) => candidate.id === workspace!.id
|
|
55
|
+
)!;
|
|
56
|
+
const [addedWindow] = current.getAllWindows();
|
|
57
|
+
expect(addedWindow.appName).to.equal(addedAppName);
|
|
58
|
+
|
|
59
|
+
// Switch into the freshly added window and verify its own UI loaded.
|
|
60
|
+
await addedWindow.forceLoad();
|
|
61
|
+
await browser.switchById(addedWindow.getGdWindow().id);
|
|
62
|
+
await $("#widget-ready").waitForDisplayed();
|
|
63
|
+
});
|
|
64
|
+
});
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { expect } from "chai";
|
|
2
|
+
import type { IOConnectDesktop } from "@interopio/desktop";
|
|
3
|
+
import type { IOConnectWorkspaces } from "@interopio/workspaces-api";
|
|
4
|
+
import { $, $$, browser } from "@wdio/globals";
|
|
5
|
+
|
|
6
|
+
// A Workspace Layout that places the two fixture apps side by side. The test
|
|
7
|
+
// imports this Layout, restores it, and drives the apps that appear in it.
|
|
8
|
+
const layoutName = "iocd-sample-people-workspace";
|
|
9
|
+
const workspaceLayout = {
|
|
10
|
+
name: layoutName,
|
|
11
|
+
type: "Workspace",
|
|
12
|
+
version: 2,
|
|
13
|
+
components: [
|
|
14
|
+
{
|
|
15
|
+
type: "Workspace",
|
|
16
|
+
state: {
|
|
17
|
+
children: [
|
|
18
|
+
{
|
|
19
|
+
type: "row",
|
|
20
|
+
children: [
|
|
21
|
+
{
|
|
22
|
+
type: "window",
|
|
23
|
+
config: { appName: "people-list" },
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
type: "window",
|
|
27
|
+
config: { appName: "person-details" },
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
} as IOConnectDesktop.Layouts.Layout;
|
|
36
|
+
|
|
37
|
+
// Restores a Workspace containing two apps, selects a person in the list app,
|
|
38
|
+
// and verifies the details app receives that selection over Interop. Exercises
|
|
39
|
+
// Workspaces, cross-app Interop, and switching the WebdriverIO context between
|
|
40
|
+
// workspace windows.
|
|
41
|
+
describe("Workspace app communication", function () {
|
|
42
|
+
this.timeout(60_000);
|
|
43
|
+
|
|
44
|
+
let workspace: IOConnectWorkspaces.Workspace | undefined;
|
|
45
|
+
|
|
46
|
+
beforeEach(async () => {
|
|
47
|
+
// Make the Workspace Layout available to restore during the test.
|
|
48
|
+
const io = await browser.io();
|
|
49
|
+
await io.layouts.import([workspaceLayout], "merge");
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
afterEach(async () => {
|
|
53
|
+
// Close the Workspace and remove the imported Layout so runs stay isolated.
|
|
54
|
+
const io = await browser.io();
|
|
55
|
+
await workspace?.close().catch(() => undefined);
|
|
56
|
+
workspace = undefined;
|
|
57
|
+
await io.layouts.remove("Workspace", layoutName).catch(() => undefined);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("displays a person selected in another workspace app", async () => {
|
|
61
|
+
const io = await browser.io();
|
|
62
|
+
|
|
63
|
+
// Restore the Workspace and locate its two app windows.
|
|
64
|
+
workspace = await io.workspaces!.restoreWorkspace(layoutName);
|
|
65
|
+
const workspaceWindows = workspace.getAllWindows();
|
|
66
|
+
const peopleListWindow = workspaceWindows.find((window) => window.appName === "people-list");
|
|
67
|
+
const personDetailsWindow = workspaceWindows.find(
|
|
68
|
+
(window) => window.appName === "person-details"
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
expect(peopleListWindow, "people-list workspace window").to.exist;
|
|
72
|
+
expect(personDetailsWindow, "person-details workspace window").to.exist;
|
|
73
|
+
|
|
74
|
+
// Force-load both windows so their web content and Interop are running.
|
|
75
|
+
await Promise.all([peopleListWindow!.forceLoad(), personDetailsWindow!.forceLoad()]);
|
|
76
|
+
|
|
77
|
+
// Switch into the list app and pick a random person.
|
|
78
|
+
await browser.switchById(peopleListWindow!.getGdWindow().id);
|
|
79
|
+
|
|
80
|
+
const people = $$("[data-person-name]");
|
|
81
|
+
const peopleCount = await people.length;
|
|
82
|
+
const selectedPerson = await people[Math.floor(Math.random() * peopleCount)];
|
|
83
|
+
const expectedName = await selectedPerson.getText();
|
|
84
|
+
|
|
85
|
+
await selectedPerson.waitForEnabled();
|
|
86
|
+
await selectedPerson.click();
|
|
87
|
+
|
|
88
|
+
// The list app invokes an Interop method the details app handles; switch to
|
|
89
|
+
// the details app and verify it displays the selected name.
|
|
90
|
+
await browser.switchById(personDetailsWindow!.getGdWindow().id);
|
|
91
|
+
|
|
92
|
+
const displayedPerson = await $("#selected-person");
|
|
93
|
+
await browser.waitUntil(async () => (await displayedPerson.getText()) === expectedName, {
|
|
94
|
+
timeoutMsg: `Expected the details app to display ${expectedName}`,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
expect(await displayedPerson.getText()).to.equal(expectedName);
|
|
98
|
+
});
|
|
99
|
+
});
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"compilerOptions": {
|
|
3
3
|
"target": "ES2020",
|
|
4
|
-
"module": "
|
|
5
|
-
"moduleResolution": "
|
|
6
|
-
"outDir": "dist",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "Bundler",
|
|
7
6
|
"esModuleInterop": true,
|
|
8
|
-
"
|
|
7
|
+
"strict": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"types": ["node", "@wdio/globals/types", "@types/mocha"]
|
|
9
10
|
},
|
|
10
|
-
"include": ["
|
|
11
|
+
"include": ["./**/*.ts"],
|
|
12
|
+
"exclude": ["node_modules"]
|
|
11
13
|
}
|
|
@@ -1,36 +1,40 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
} from "@interopio/wdio-iocd-service";
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { IOCDBaseConfiguration, IOCDService } from "@interopio/wdio-iocd-service";
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
const rootDir = path.dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
process.env.WDIO_TESTS_ROOT = path.resolve(rootDir, "tests");
|
|
7
|
+
process.env.WDIO_ROOT_DIR = rootDir;
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
const binary = process.env.BINARY_PATH;
|
|
10
|
+
if (!binary) {
|
|
11
|
+
throw new Error("BINARY_PATH is not set. Run the suite from the seed root with 'iocd test'.");
|
|
12
|
+
}
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
export const config: WebdriverIO.Config = {
|
|
15
|
+
...IOCDBaseConfiguration,
|
|
16
|
+
services: IOCDService({ videoRecording: { enabled: false } }),
|
|
17
|
+
framework: "@interopio/wdio-iocd-service/framework",
|
|
18
|
+
reporters: ["spec"],
|
|
19
|
+
logLevel: "warn",
|
|
20
|
+
waitforInterval: 200,
|
|
21
|
+
waitforTimeout: 5000,
|
|
22
|
+
mochaOpts: { ui: "bdd", timeout: 60000, groupSuites: false },
|
|
13
23
|
capabilities: [
|
|
14
24
|
{
|
|
15
25
|
browserName: "iocd",
|
|
16
|
-
"
|
|
26
|
+
"iocd:runner": "platform-wdio",
|
|
17
27
|
"iocd:options": {
|
|
18
|
-
binary
|
|
28
|
+
binary,
|
|
29
|
+
ioInitOptions: {
|
|
30
|
+
appManager: "full",
|
|
31
|
+
layouts: "full",
|
|
32
|
+
channels: true,
|
|
33
|
+
libraries: ["@interopio/workspaces-api"],
|
|
34
|
+
},
|
|
35
|
+
configOverrides: [path.resolve(rootDir, "config/system.json")],
|
|
19
36
|
},
|
|
37
|
+
"wdio:specs": [["./tests/**/*.spec.ts"]],
|
|
20
38
|
},
|
|
21
39
|
],
|
|
22
|
-
|
|
23
|
-
// WDIO Options
|
|
24
|
-
logLevel: "warn",
|
|
25
|
-
framework: "mocha",
|
|
26
|
-
reporters: ["spec"],
|
|
27
|
-
|
|
28
|
-
// TypeScript Autocompile
|
|
29
|
-
autoCompileOpts: {
|
|
30
|
-
autoCompile: true,
|
|
31
|
-
tsNodeOpts: {
|
|
32
|
-
transpileOnly: true,
|
|
33
|
-
project: "./tsconfig.json",
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
40
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@interopio/iocd-cli",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "CLI tool for setting up, building and packaging io.Connect Desktop platforms",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=22.0.0",
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
"lint": "eslint src --ext .ts",
|
|
21
21
|
"lint:fix": "eslint src --ext .ts --fix",
|
|
22
22
|
"format": "prettier --write src/**/*.ts*",
|
|
23
|
-
"
|
|
23
|
+
"audit:production": "npm audit --omit=dev --audit-level=critical",
|
|
24
|
+
"prepublishOnly": "npm run audit:production && npm run build && npm run gitignore:pre-package",
|
|
24
25
|
"postpublish": "npm run gitignore:post-publish",
|
|
25
26
|
"postinstall": "npm run gitignore:post-install",
|
|
26
27
|
"gitignore:pre-package": "node ./scripts/handle-gitignore-templates.js pre-package",
|
|
@@ -51,7 +52,7 @@
|
|
|
51
52
|
"@electron/notarize": "^3.1.0",
|
|
52
53
|
"@electron/osx-sign": "^2.2.0",
|
|
53
54
|
"@sentry/node": "^10.17.0",
|
|
54
|
-
"adm-zip": "^0.
|
|
55
|
+
"adm-zip": "^0.6.0",
|
|
55
56
|
"commander": "^14.0.0",
|
|
56
57
|
"concurrently": "^10.0.3",
|
|
57
58
|
"dotenv": "^17.2.2",
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
describe("Example usage of @interopio/wdio-iocd-service", () => {
|
|
2
|
-
it("should have access to browser.io()", async () => {
|
|
3
|
-
// A fully working io.Connect Desktop client
|
|
4
|
-
const io = await browser.io();
|
|
5
|
-
|
|
6
|
-
expect(io).toHaveAttribute("appManager");
|
|
7
|
-
expect(io).toHaveAttribute("contexts");
|
|
8
|
-
expect(io).toHaveAttribute("channels");
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
it("should raise a test notifications, and then navigate to notifications panel", async () => {
|
|
12
|
-
const io = await browser.io();
|
|
13
|
-
await io.notifications.configure({ enable: true });
|
|
14
|
-
await io.notifications.raise({
|
|
15
|
-
title: "Test Notification title",
|
|
16
|
-
body: "Test Notification body",
|
|
17
|
-
toastExpiry: 999999,
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
await browser.switchToLaunchpad();
|
|
21
|
-
await browser.$(".notifications-button button").waitAndClick();
|
|
22
|
-
await browser.switchToNotificationPanel();
|
|
23
|
-
await browser.pause(2000);
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it("should allow using the desktop-client prefs API", async () => {
|
|
27
|
-
const io = await browser.io();
|
|
28
|
-
|
|
29
|
-
const sampleApp = "ExampleApplication";
|
|
30
|
-
const mockedAppPrefs = { lazyLoadAssets: true };
|
|
31
|
-
|
|
32
|
-
// used to store the "update" for app prefs
|
|
33
|
-
let expectedSetPrefs = null;
|
|
34
|
-
|
|
35
|
-
// Subscribe for changes on the sampleApp prefs
|
|
36
|
-
io.prefs.subscribeFor(sampleApp, ({ data }) => (expectedSetPrefs = data));
|
|
37
|
-
|
|
38
|
-
await io.prefs.setFor(sampleApp, mockedAppPrefs);
|
|
39
|
-
|
|
40
|
-
// expect the changed prefs to match what was set
|
|
41
|
-
expect(expectedSetPrefs).toMatchObject(mockedAppPrefs);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it("should allow opening apps from the appManager API", async () => {
|
|
45
|
-
const io = await browser.io();
|
|
46
|
-
|
|
47
|
-
// Start the client list app
|
|
48
|
-
const instanceClientList = await io.appManager
|
|
49
|
-
.application("channelsclientlist")
|
|
50
|
-
.start();
|
|
51
|
-
|
|
52
|
-
// Switch to the client list window
|
|
53
|
-
const clientListWindow = await instanceClientList.getWindow();
|
|
54
|
-
await browser.switchById(clientListWindow.id);
|
|
55
|
-
|
|
56
|
-
// Check that the app-client-list element exists in DOM
|
|
57
|
-
const appClientListElement = await $("app-client-list");
|
|
58
|
-
await expect(appClientListElement).toBeExisting();
|
|
59
|
-
|
|
60
|
-
// Start the client portfolio app
|
|
61
|
-
const instancePortfolio = await io.appManager
|
|
62
|
-
.application("channelsclientportfolio")
|
|
63
|
-
.start();
|
|
64
|
-
|
|
65
|
-
// Switch to the client portfolio window
|
|
66
|
-
const clientPortfolioList = await instancePortfolio.getWindow();
|
|
67
|
-
await browser.switchById(clientPortfolioList.id);
|
|
68
|
-
|
|
69
|
-
// Check that the app-client-portfolio element exists in DOM
|
|
70
|
-
const clientPortfolioElement = await $("app-client-portfolio");
|
|
71
|
-
await expect(clientPortfolioElement).toBeExisting();
|
|
72
|
-
});
|
|
73
|
-
});
|