Giter VIP home page Giter VIP logo

wdio-vscode-service's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wdio-vscode-service's Issues

Help for openContextMenu in TextEditor

Hello,

I'm writing test for private extension.
I want to automate the opening of the contextMenu to send command by click.

When i open the contextMenu

const workbench = await browser.getWorkbench();
const editorView = workbench.getEditorView();
const currentEditor = await editorView.openEditor(`${fic}`) as TextEditor;
const mnu = await currentEditor.openContextMenu();

I've got the error

invalid argument: invalid argument: invalid locator
  (Session info: chrome=102.0.5005.167)
    at getErrorFromResponseBody (C:\dev\webio\adv-e2e\node_modules\webdriver\build\utils.js:198:12)
    at NodeJSRequest._request (C:\dev\webio\adv-e2e\node_modules\webdriver\build\request\index.js:166:60)
    at async Browser.wrapCommandFn (C:\dev\webio\adv-e2e\node_modules\@wdio\utils\build\shim.js:137:29)
    at async Browser.$ (C:\dev\webio\adv-e2e\node_modules\@wdio\runner\node_modules\webdriverio\build\commands\browser\$.js:91:17)
    at async Browser.wrapCommandFn (C:\dev\webio\adv-e2e\node_modules\@wdio\utils\build\shim.js:137:29)
    at async ContextMenu.wait (C:\dev\webio\adv-e2e\node_modules\wdio-vscode-service\src\pageobjects\menu\ContextMenu.ts:80:16)
    at async World.<anonymous> (C:\dev\webio\adv-e2e\e2e\step-definitions\vscode.step.ts:82:21)

On debugging my test, I see the menu opening but it hangs just after

Is it possible to use a singleton across all tests? Or is it possible to run the test suites sequentially?

Our extension relies on a dependency, and we need to manage when and how the dependency runs. When our test suites run, they run in parallel and when we run this dependency, we've found that it needs to run sequentially, just one at a time, and this conflicts with our test suites which are running in parallel.

To overcome this, I tried creating a singleton to manage the resource, but I've since found out that each test suite (eg a.e2e.ts, b.e2e.ts, c.e2e.ts, etc...) runs in its own (siloed) memory space.

So when a.e2e.ts runs, Singleton.instance is null and an instance of Singleton() is created (which is expected),
and when b.2e.ts runs, Singleton.instance is ALSO null and a new instance of Singleton() is created (which is not expected),
and when c.2e.ts runs, Singleton.instance is ALSO null...
etc...

I have two questions:

  1. Is it possible to have a singleton be accessible to the various test suites?
  2. When our test suites run, they run at the same time and in parallel. Is it possible to configure a project, so that the test suites run sequentially and only run one test suite at a time? I think if we were able to run the tests suites in series instead of parallel, that would negate the need for us to manage this resource and would negate the need for a singleton.

Thanks,

Jeff

Provided binary setting is ignored if versions.txt file exists

On the 2nd call / when the versions.txt file exists the provided binary settings gets overwritten/ignored/not used.

Imho line:

cap[VSCODE_CAPABILITY_KEY].binary = await this._downloadVSCode(content[version]?.vscode as string)

should be changed e.g. to
cap[VSCODE_CAPABILITY_KEY].binary = cap[VSCODE_CAPABILITY_KEY].binary || await this._downloadVSCode(content[version]?.vscode as string)

`resetPosition` triggers `The setValue/addValue command only take string or number values`

After upgrading from 4.x to 5.x I'm getting the following error:

Error: The setValue/addValue command only take string or number values. If you like to use special characters, use the "keys" command.
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async InputBox.setText (file:///Users/fabian.jakobs/Workspaces/databricks-vscode/packages/databricks-vscode/node_modules/wdio-vscode-service/src/pageobjects/workbench/Input.ts:53:9)
    at async InputBox.resetPosition (file:///Users/fabian.jakobs/Workspaces/databricks-vscode/packages/databricks-vscode/node_modules/wdio-vscode-service/src/pageobjects/workbench/Input.ts:248:6)
    at async InputBox.findQuickPick (file:///Users/fabian.jakobs/Workspaces/databricks-vscode/packages/databricks-vscode/node_modules/wdio-vscode-service/src/pageobjects/workbench/Input.ts:173:10)
    at async InputBox.selectQuickPick (file:///Users/fabian.jakobs/Workspaces/databricks-vscode/packages/databricks-vscode/node_modules/wdio-vscode-service/src/pageobjects/workbench/Input.ts:137:19)

The error is triggered by calling await input.selectQuickPick("DEFAULT");, which internally calls resetPosition.

I've patched the issues by changing:

await this.setText(text)

to

await this.setText(text || "")

TreeSection.openItem() doesn't work with compacted folders

TreeSection.openItem() doesn't work with compacted (empty) folders.

Let's say I have the following folder structure:

/src
/src/project
/src/project/test
/src/project/test/two
/src/project/test/two/three
/src/project/test/two/three/example.ts

...and let's say that in my e2e test, I have /src/project open. When /src/project is opened, VS Code displays just:

PROJECT
  test

If /project/test is expanded, because VS Code has the explorer.compactFolders setting set to true by default, what we see is:

PROJECT
  test / two / three
    example.ts

(/project/test only has one folder, "two", and project/test/two only has one folder, "three", and so they are compacted)

OK, next write a test and add:

const item = await treeViewSection.openItem('test');

The implementation of openItem() is:

class TreeSection extends ViewSection_1.ViewSection {
    async openItem(...path) {
        let items = [];
        for (let i = 0; i < path.length; i += 1) {
            const item = await this.findItem(path[i], i + 1);
            if (await item?.hasChildren() && !await item?.isExpanded()) {
                await item?.expand();
            }
        }
        let currentItem = await this.findItem(path[0], 1);
        for (let i = 0; i < path.length; i += 1) {
        .
        .
        .

Here, path is ['test'], and in the first loop, when findItem() is called:

            const item = await this.findItem(path[i], i + 1);

...i is 0, and path[0] is "test", this.findItem(path[i], i + 1) succeeds, and then the node is expanded in VS Code's UI.

But next, immediately after the first for loop, findItem() is called again:

        let currentItem = await this.findItem(path[0], 1);

path[0] is still "test", but since the node was expanded, and it has nested empty folders, and explorer.compactFolders is true by default, the text of the node is now "test / two / three", and currentItem returned from this.findItem(path[0], 1) is undefined.

Continue support for CommonJS

Trying to use v5 of the service with a CommonJS module results in:

Error: Error: Cannot find module '/path/to/node_modules/wdio-vscode-service/dist/cjs/index.js'`

I've seen that package.json is set up to handle both ESM and CommonJS versions but I think the build needs to be updated to produce the different types.

Unable to clear editor text for VSCode web

The clearText test fails due to the following error:

Command failed: D:\a\wdio-vscode-service\wdio-vscode-service\node_modules\clipboardy\fallbacks\windows\clipboard_x86_64.exe --paste
thread 'main' panicked at 'Error: Could not paste from clipboard: Error { repr: Os { code: -2147221398, message: "Invalid clipboard format" } }', src\libcore\result.rs:906:4
note: Run with `RUST_BACKTRACE=1` for a backtrace.

This seems to be only for Windows.

Unexpected behavior when use Element setValue with string that contains keyword "var".

Hi, how are you?

I try to open a discussion before create an issue, but the section was disabled for the repository..

I have an issue with custom page object for the quick input header.. when i try to set to the element a value that contains "var" the same was not setted, and the component gets updated with the root path of the file system..

I create a little example, and in this test you could check the described behavior.

Unable to download chromedriver for insiders version of VS Code

Ran into this issue in our CI this morning.

From digging in it appears that the list of available drivers no longer matches what the service expects:

https://chromedriver.storage.googleapis.com/index.html?path=108.0.5359.71/

image

vs

https://chromedriver.storage.googleapis.com/index.html?path=102.0.5005.61/

image

Looks like there needs to be an update in validatePlatform. Unfortunately, it seems like either we will need to pass the version of chromedriver to this function and switch based of it or call a different function entirely after v108 of chromedriver. WDYT?

Let me know which approach you'd prefer and I'll raise a PR 🙏🏻.

Terminal getText not working correctly

The getText method from TerminalView is not working correctly.
It selects the Terminal output executing the wrong copy command: terminal copy selection
There is no such command.
One alternative could be to modify the command to use copy

Reproduction example:

 const workbench = await browser.getWorkbench()
 const bottomBar = workbench.getBottomBar()
 const terminalView = await bottomBar.openTerminalView()
 const text = await terminalView.getText() // returns empty value

A temporary workaround:

 import clipboard from 'clipboardy'

 const workbench = await browser.getWorkbench()
 await workbench.executeCommand('Terminal select all')
 await workbench.executeCommand('Copy')

// Use the clipboard to get the copied text.
  const text = await clipboard.read()
  await clipboard.write('')

Unable to get wdio-vscode-service working from workspace directory with a long path

I made a very bare bones example based on your docs. It doesn't work from my normal project folder /Users/fabian.jakobs/Desktop/Workspaces/wdio but it does work when copying it to /tmp and running it from there. I was running into similar issues before where the full VSCode executable path had to be below a certain length but this time I'm unable to fix it.

Setting cachePath to /tmp also didn't help.

VSCode never even starts in the first case.

Hosted VS Code Web

I would like to run tests against a VS Code instances that is hosted in my cloud (similar to vscode.dev).
So it would be great, if I could stop the testrunner from starting vscode web locally, but rather point it towards my (already running) instance.
I did not find a way to do this, but there seemed to be some preparation in the code for this use case.

The variable _vscodeServerPort in VSCodeServiceLauncher is checked before starting the server:

      /**
         * no need to do any work if we already started the server
         */
        if (this._vscodeServerPort || !cap[VSCODE_CAPABILITY_KEY]) {
            return
        }

but _vscodeServerPort is never set anywhere.

So my proposal would be:

-- a/src/launcher.ts
+++ b/src/launcher.ts
@@ -56,6 +56,7 @@ export default class VSCodeServiceLauncher extends ChromedriverServiceLauncher {
     ) {
         super(_options, _capabilities, config)
         this._cachePath = this._options.cachePath || DEFAULT_CACHE_PATH
+        this._vscodeServerPort = this._capabilities[VSCODE_CAPABILITY_KEY]?.serverOptions?.port
         this._mapCapabilities = () => {}
     }

Is this viable?

Npm founds 4 vulnerabilities (3 moderate, 1 high)

My version of wdio-vscode-service is 4.0.7
Get the following information on running npm audit fix

node_modules/download/node_modules/got
  download  >=4.0.0
  Depends on vulnerable versions of got
  node_modules/download

undici  <=5.8.1
Severity: high
undici before v5.8.0 vulnerable to CRLF injection in request headers - https://github.com/advisories/GHSA-3cvr-822r-rqcc
ProxyAgent vulnerable to MITM - https://github.com/advisories/GHSA-pgw7-wx7w-2w33
`undici.request` vulnerable to SSRF using absolute URL on `pathname` - https://github.com/advisories/GHSA-8qr4-xgw6-wmr3
Nodejs ‘undici’ Vulnerable to CRLF Injection via Content-Type - https://github.com/advisories/GHSA-f772-66g8-q5h3
undici before v5.8.0 vulnerable to uncleared cookies on cross-host / cross-origin redirect - https://github.com/advisories/GHSA-q768-x9m6-m9qp
No fix available
node_modules/undici
  wdio-vscode-service  *
  Depends on vulnerable versions of download
  Depends on vulnerable versions of undici
  node_modules/wdio-vscode-service

4 vulnerabilities (3 moderate, 1 high)

Updating the mentioned dependent packages inside of package-lock.json removed these vulnerabilities for me.

Might want to check your dependencies! :)

Is it possible to debug a function callback that's passed into executeWorkbench()?

The vscode instance/object can't be directly called, and I read that the preferred pattern is to do this:

import vscodeType from 'vscode'

const openFile = async (vscode: typeof vscodeType, file: string) => {
  const fsPath = vscode.Uri.parse(file).fsPath;
  const doc = await vscode.workspace.openTextDocument(fsPath);
  const editor = await vscode.window.showTextDocument(doc);
}


it('opens a file', async () => {
    await browser.executeWorkbench(openFile, '/Users/my-user-name/temp/test.txt');
});

This works, however, I'd like to be able to step into the callback function and debug it. (this example is pretty simple, but I have another one which isn't working and I would like to be able to debug it)

I've tried adding breakpoints, and I've tried adding debugger. I know the code is getting executed (in this situation the file is getting opened), but I'm not able to actually debug the code. I was wondering if anyone here has any tips or suggestions on how to do this?

Thanks!

Jeff

Command `browser.executeWorkbench` doesn't allow to pass in more params

The executeWorkbench does not allow to have additional parameters, I'ld suggest to change it to the following:

executeWorkbench: <T>(fn: (vscode: any, ...params: any[]) => T) => Promise<T>;
executeWorkbench: <T>(fn: (vscode: any, ...params: any[]) => T, ...params: any[]) => Promise<T>;

Additional points if the types added to the command are propagated to the callback function.

Not able to run tests against a VSIX

At the moment, one specifies where there extension's code is located by setting the extensionPath setting in wdio.conf.ts, and this location is the path to the extension's source files. We would like the ability to instead run the tests agains a VSIX that had been built.

Running tests in Docker

Hello Team!

I'm trying to run wdio tests in a docker container and I can't make it work. The aim is to run wdio tests at a CI environment.

I start from a simple hello world project. Docker image starts from ubuntu:20.04 and I add some packages to compile and run tests. Nothing out of the standard stuff. We set Xvfb to run tests at a CI environment (Jenkins). I need java for other tasks.

FROM ubuntu:20.04

ENV DEBIAN_FRONTEND noninteractive

RUN apt-get update

# Install required packages
RUN apt-get install --yes --no-install-recommends \
    dirmngr \ 
    gpg \
    build-essential \
    libgconf-2-4 \
    libgtk-3-0 \
    xvfb \
    libnss3-dev \
    libgbm-dev \
    libasound2 \
    xauth \
    awscli \
    npm \
    curl \
    openjdk-11-jdk-headless

# Install node
RUN curl -s https://deb.nodesource.com/setup_16.x | bash
RUN apt-get install nodejs -y
RUN node --version
RUN npm --version

# Setup screen
RUN Xvfb :99 -screen 0 1280x1024x24 -ac &

When running as a non root user, the I get this message:

2022-07-28T14:01:52.799Z INFO chromedriver: [FAKE VSCode Binary] STDERR: [812:0728/140152.797845:FATAL:setuid_sandbox_host.cc(158)] The SUID sandbox helper binary was found, but is not configured correctly. Rather than run without sandboxing I'm aborting now. You need to make sure that /home/xxxxxxx/webdriver-test/.wdio-vscode-service/vscode-linux-x64-1.69.2/chrome-sandbox is owned by root and has mode 4755.

After applying the requested changes, I get the following:

2022-07-28T14:45:12.258Z INFO chromedriver: [FAKE VSCode Binary] STDERR: Failed to move to new namespace: PID namespaces supported, Network namespace supported, but failed: errno = Operation not permitted

Is there something missing? I see that your Github action works like charm.

Thank you!

getActionButtons() fails for CustomTreeItems due to containers being undefined

I try to add a test for my extension that has a tree view. In the tree view I can access the tree and e.g. call getLabel().
But trying to get the action buttons fails with
Cannot read properties of undefined (reading 'isExisting')

imho accessed from here:

if (!await container.isExisting()) {

Used versions:
mac (arm)
wdio-vscode-service 4.0.5
VSCode v1.70.2 (vscode-darwin-arm64-1.70.2 stable) and Chromedriver v100.0.4896.60

Any help appreciated!
(I tried the same/similar tests with vscode-extension-tester (just noticed that I tried it there with vscode 1.67.0) and can access the tree-view and trigger the action buttons without issues. But I'd prefer to use wdio-vscode-service as it seems to be magnitudes faster :-)

openContextMenu() times out and fails

I'm writing a test which is automating the Explorer's tree view. I obtain the items in the view like so:

const treeViewSection = await sidebar.getContent().getSection('MY-PROJECT');
await treeViewSection.expand();
const visibleItems = (await treeViewSection.getVisibleItems()) as DefaultTreeItem[];

From visibleItems I then find the item/node I'm looking for (named, "viewItem" - which, at runtime, is a DefaultTreeItem)

I then call:

const contextMenu = await viewItem.openContextMenu();

...and I get the following error:

// Error: element (".monaco-menu-container") still not displayed after 5000ms
// at async ContextMenu.wait (/my-path/my-project/node_modules/wdio-vscode-service/src/pageobjects/menu/ContextMenu.ts:80:9)
// at async Context.<anonymous> (/my-path/my-project/test/specs/my-test-suite.e2e.ts:150:29)

Is there a bug here, or am I going about trying to get the contextual menu wrong?
I should also point out that

  1. When this runs, the contextual menu for that item does actually appear, and appears before the error is logged. Maybe the locator for that page object is stale/out of date with VS Code? I'm running version 1.71.1, on OSX.
  2. The overall goal of this is to find a specific item in the Explorer tree, open its contextual menu, and then run a command. I was planning on doing:
const contextMenu = await viewItem.openContextMenu();
const menuItem = await contextMenu.getItem('my-command');
const menu = await menuItem.select();

...and if there's a better way to do this, please let me know.

CodeLens page object only supports one CodeLense per row/group

Our extension implements a few code lenses, and most of our code lens providers emit two code lenses per provider.

(eg a single row with "Run code | Debug code")

(also, for clarity, I'm referring to each link ("Run code" or "Debug code") as a separate code lens, not "Run code | Debug code" as a single code lens)

The CodeLens class (in TextEditor.ts) only returns the first anchor tag when getText() is called. This is because elem.$('a') is called instead of elem.$$('a'), and the page object definition for a CodeLens assumes there is only one code lens in the code lens's container.

    async getText (): Promise<string> {
        const link = await this.elem.$('a')
        return link.getText()
    }

Importing globals (browser, $, and $$)

We are using wdio-service-vscode 4.1.0 (we should probably update to 4.2.1 but we can't update to v5). In our code we have many places where we use browser, $, and $$.

The code runs fine but we've turned on strict mode and are getting errors about browser and the others not being defined.

Looking through the examples for wdio-service-vscode I see

import { browser, expect, $ } from '@wdio/globals'

in v5.0.0
(https://github.com/webdriverio-community/wdio-vscode-service/blob/5.0.0/test/specs/basic.e2e.ts)

...but not in v4.2.1
(https://github.com/webdriverio-community/wdio-vscode-service/blob/4.2.1/test/specs/basic.e2e.ts)

Due to the change in how modules are exported we aren't able to update to v5.

In v4.2.1 (or v4.1.0), is it possible to import these globals, so strict mode doesn't complain about them? Yes, we can add a TS comment to silence the warning, but this would need to be done in many places and I don't want to do that.

I've tried many things (like adding @wdio/globals to list of dependencies in our project's package.json) but nothing has worked out, so I'm wondering, how does one use strict mode and import browser and $ (in v4.x)?

Fresh wdio-vscode-service project is not starting, because of 3.0.8 vscode-uri

Steps to reproduce:
Create wdio project for vscode extension testing - npm create wdio ./
Run it - npm run wdio
Error:

F:\Projects\webdriver.io\uri-bug>npm run wdio

> wdio
> wdio run ./wdio.conf.ts


Execution of 1 workers started at 2023-10-13T18:31:09.764Z

2023-10-13T18:31:17.841Z INFO @wdio/local-runner: Shutting down spawned worker
2023-10-13T18:31:18.094Z INFO @wdio/local-runner: Waiting for 0 to shut down gracefully
2023-10-13T18:31:18.095Z INFO @wdio/local-runner: shutting down
Error: Error: Failed to initilialise launcher service unknown: Error: Couldn't initialise "wdio-vscode-service".
TypeError: Cannot destructure property 'URI' of '(intermediate value).default' as it is undefined.
    at file:///F:/Projects/webdriver.io/uri-bug/node_modules/wdio-vscode-service/src/server/utils.ts:6:9
    at safeImport (file:///F:/Projects/webdriver.io/uri-bug/node_modules/@wdio/utils/build/utils.js:210:15)
    at async initialisePlugin (file:///F:/Projects/webdriver.io/uri-bug/node_modules/@wdio/utils/build/initialisePlugin.js:32:20)
    at async initialiseServices (file:///F:/Projects/webdriver.io/uri-bug/node_modules/@wdio/utils/build/initialiseServices.js:53:25)
    at async initialiseLauncherService (file:///F:/Projects/webdriver.io/uri-bug/node_modules/@wdio/utils/build/initialiseServices.js:81:26)
    at async Launcher.run (file:///F:/Projects/webdriver.io/uri-bug/node_modules/@wdio/cli/build/launcher.js:81:65)
    at initialiseLauncherService (file:///F:/Projects/webdriver.io/uri-bug/node_modules/@wdio/utils/build/initialiseServices.js:118:15)
    at async Launcher.run (file:///F:/Projects/webdriver.io/uri-bug/node_modules/@wdio/cli/build/launcher.js:81:65)
Error: Failed to initilialise launcher service unknown: Error: Couldn't initialise "wdio-vscode-service".
TypeError: Cannot destructure property 'URI' of '(intermediate value).default' as it is undefined.
    at file:///F:/Projects/webdriver.io/uri-bug/node_modules/wdio-vscode-service/src/server/utils.ts:6:9
    at safeImport (file:///F:/Projects/webdriver.io/uri-bug/node_modules/@wdio/utils/build/utils.js:210:15)
    at async initialisePlugin (file:///F:/Projects/webdriver.io/uri-bug/node_modules/@wdio/utils/build/initialisePlugin.js:32:20)
    at async initialiseServices (file:///F:/Projects/webdriver.io/uri-bug/node_modules/@wdio/utils/build/initialiseServices.js:53:25)
    at async initialiseLauncherService (file:///F:/Projects/webdriver.io/uri-bug/node_modules/@wdio/utils/build/initialiseServices.js:81:26)
    at async Launcher.run (file:///F:/Projects/webdriver.io/uri-bug/node_modules/@wdio/cli/build/launcher.js:81:65)
    at initialiseLauncherService (file:///F:/Projects/webdriver.io/uri-bug/node_modules/@wdio/utils/build/initialiseServices.js:118:15)
    at async Launcher.run (file:///F:/Projects/webdriver.io/uri-bug/node_modules/@wdio/cli/build/launcher.js:81:65)

Workaround is to run npm install [email protected]

Fault location inside wdio-vscode-service with vscode-uri v3.0.8:
'src/server/utils.ts' line 6:

...
const { URI } = (await import('vscode-uri')).default
...

--disable-extensions flag

As by default webdriver starts vscode with --disable-extension flag, I need to reload the window to make extensions work. I add the code to reload the window at beforeSuite method. My question is why are extensions disabled? Could we remove the flag?
See

disableExtensions: true

Calling sleep() is causing an error of "Unable to load spec files"

I'm attempting to upgrade our project from wdio-vscode-service 4.1.0 to 5.0.0. I've encountered a few issues (more on that later), but I've encountered (what I think is) an "out of the box" error, which code which contains calls to sleep() is causing an error of

Error:  Unable to load spec files quite likely because they rely on `browser` object that is not fully initialised.
`browser` object has only `capabilities` and some flags like `isMobile`.
Helper files that use other `browser` commands have to be moved to `before` hook.
Spec file(s): file:///my-username/temp/new-wdio-test/test/specs/example.e2e.ts
Error: Error: Cannot find module '/my-username/temp/new-wdio-test/node_modules/wdio-vscode-service/dist/cjs/index.js'
    at createEsmNotFoundErr (node:internal/modules/cjs/loader:960:15)
    at finalizeEsmResolution (node:internal/modules/cjs/loader:953:15)
    at resolveExports (node:internal/modules/cjs/loader:482:14)
    at Function.Module._findPath (node:internal/modules/cjs/loader:522:31)
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:919:27)
    at Function.Module._resolveFilename.sharedData.moduleResolveFilenameHook.installedValue [as _resolveFilename] (/my-username/temp/new-wdio-test/node_modules/@cspotcode/source-map-support/source-map-support.js:811:30)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (/my-username/temp/new-wdio-test/test/specs/example.e2e.ts:5:1)
    at Module._compile (node:internal/modules/cjs/loader:1103:14)
    at Module.m._compile (/my-username/temp/new-wdio-test/node_modules/ts-node/src/index.ts:1618:23)
    at Module._extensions..js (node:internal/modules/cjs/loader:1155:10)
    at Object.require.extensions.<computed> [as .ts] (/my-username/temp/new-wdio-test/node_modules/ts-node/src/index.ts:1621:12)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
[0-0] FAILED in chrome - file:///test/specs/example.e2e.ts

It's hard to tell from this error... the error being reported says the browser object isn't being initialized,
but it's also saying that it can't find node_modules/wdio-vscode-service/dist/cjs/index.js, and I can confirm that node_modules/wdio-vscode-servicedist/cjs doesn't exist.

Steps to reproduce:

  1. Follow the installation and configuration steps listed at https://github.com/webdriverio-community/wdio-vscode-service/tree/main/test
    (note, there are some steps in this README that are stale and need to be updated - I'll probably create a PR with updated steps later)
  2. Modify /test/specs/example.e2e.ts to:
import LoginPage from '../pageobjects/login.page'
import SecurePage from '../pageobjects/secure.page'

import {
    sleep
} from 'wdio-vscode-service';

describe('My Login application', () => {
    it('should login with valid credentials', async () => {
        /*
        await LoginPage.open()

        await LoginPage.login('tomsmith', 'SuperSecretPassword!')
        await expect(SecurePage.flashAlert).toBeExisting()
        await expect(SecurePage.flashAlert).toHaveTextContaining(
            'You logged into a secure area!')
        */
        sleep(1000);
        expect(1).toBe(1);
    })
})
  1. go back to the terminal and run npm run wdio

Results:

  • You get the error I mentioned above.
  • If you comment out the call to sleep() (but still import it) an run the test again, the test passes.

If needed, I can zip up the project and attach it to this ticket.

Unable to start vscode with wdio runner (unknown error: DevToolsActivePort file doesn't exist)

Hi! I'm currently working on installed wdio to help with testing a vscode extension. When I try and run the boilerplate test file that was created through the wizard I'm getting the following error:

ERROR webdriver: Request failed with status 500 due to unknown error: unknown error: Chrome failed to start: exited abnormally.
[0-0]   (unknown error: DevToolsActivePort file doesn't exist

What I'm finding strange is that I'm able to manually run the chromium/index.js file and provide all of the same flags that are provided as when I run the wdio run command and successfully start the emulated vscode instance. When I run wdio run wdio.conf.js , the vscode instance never starts and I get the above error.

2023-08-23T19:19:10.044Z DEBUG @wdio/utils:initialiseServices: initialise service "vscode" as NPM package
2023-08-23T19:19:10.449Z INFO chromedriver: Initiate Chromedriver Launcher (v8.1.1)
2023-08-23T19:19:10.449Z INFO @wdio/cli:launcher: Run onPrepare hook
2023-08-23T19:19:10.459Z INFO wdio-vscode-service/launcher: Fetch releases from https://update.code.visualstudio.com/api/releases/stable
2023-08-23T19:19:11.124Z INFO wdio-vscode-service/launcher: Download Chromedriver (v108.0.5359.71)
2023-08-23T19:19:14.788Z INFO chromedriver: Start Chromedriver (path/to/extension/.wdio-vscode-service/chromedriver-108.0.5359.71) with args --port=9515 --url-base=/
2023-08-23T19:19:15.048Z INFO chromedriver: Starting ChromeDriver 108.0.5359.71 (1e0e3868ee06e91ad636a874420e3ca3ae3756ac-refs/branch-heads/5359@{#1016}) on port 9515
2023-08-23T19:19:15.049Z INFO chromedriver: Only local connections are allowed.
2023-08-23T19:19:15.049Z INFO chromedriver: Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
2023-08-23T19:19:15.050Z INFO chromedriver: ChromeDriver was started successfully.
2023-08-23T19:19:15.142Z DEBUG @wdio/cli:utils: Finished to run "onPrepare" hook in 4692ms
2023-08-23T19:19:15.144Z INFO @wdio/utils: Setting up browser driver for: vscode@stable
2023-08-23T19:19:15.144Z INFO @wdio/utils: Setting up browser binaries for: vscode@stable
2023-08-23T19:19:15.151Z INFO @wdio/cli:launcher: Run onWorkerStart hook
2023-08-23T19:19:15.152Z DEBUG @wdio/cli:utils: Finished to run "onWorkerStart" hook in 0ms
2023-08-23T19:19:15.153Z INFO @wdio/local-runner: Start worker 0-0 with arg: run,./src/test/wdio.conf.js
2023-08-23T19:19:15.178Z DEBUG @wdio/local-runner: Send command run to worker with cid "0-0"
[0-0] 2023-08-23T19:19:16.347Z INFO @wdio/local-runner: Run worker command: run
[0-0] 2023-08-23T19:19:16.358Z DEBUG @wdio/runner: init remote session
[0-0] 2023-08-23T19:19:16.361Z DEBUG @wdio/utils:initialiseServices: initialise service "vscode" as NPM package
[0-0] 2023-08-23T19:19:16.811Z INFO wdio-vscode-service: Start VSCode proxy server on port 56358
[0-0] 2023-08-23T19:19:16.812Z INFO wdio-vscode-service: Setting up VSCode directory at /var/folders/0n/p0zc4r5j4bz1f0d5br0yv_4r0000gn/T/tmp-35684-o6rrwnUFh2FX/settings/User
[0-0] 2023-08-23T19:19:16.815Z INFO wdio-vscode-service: Start VSCode: path/to/extension/node_modules/wdio-vscode-service/dist/chromium/index.js --no-sandbox --disable-updates --skip-welcome --skip-release-notes --disable-workspace-trust --disable-extensions --extension-development-path=path/to/extension/src --extension-tests-path=path/to/extension/node_modules/wdio-vscode-service/dist/proxy/cjs/entry.js --user-data-dir=/var/folders/0n/p0zc4r5j4bz1f0d5br0yv_4r0000gn/T/tmp-35684-o6rrwnUFh2FX/settings --extensions-dir=/var/folders/0n/p0zc4r5j4bz1f0d5br0yv_4r0000gn/T/tmp-35684-o6rrwnUFh2FX/extensions --vscode-binary-path="path/to/extension/.wdio-vscode-service/vscode-darwin-1.81.1/Visual Studio Code.app/Contents/MacOS/Electron"
[0-0] 2023-08-23T19:19:16.816Z DEBUG @wdio/utils:shim: Finished to run "beforeSession" hook in 11ms
[0-0] ACTUALLY RUNING TEH TEST
[0-0] RUNNING in chrome - file:///src/test/specs/test.e2e.mjs
[0-0] 2023-08-23T19:19:16.924Z DEBUG @wdio/runner: init remote session
[0-0] 2023-08-23T19:19:16.926Z INFO webdriver: Initiate new session using the WebDriver protocol
[0-0] 2023-08-23T19:19:16.926Z INFO @wdio/utils: Connecting to existing driver at http://localhost:9515/
[0-0] 2023-08-23T19:19:16.951Z INFO webdriver: [POST] http://localhost:9515/session
[0-0] 2023-08-23T19:19:16.952Z INFO webdriver: DATA {
[0-0]   capabilities: {
[0-0]     alwaysMatch: {
[0-0]       browserName: 'chrome',
[0-0]       browserVersion: 'stable',
[0-0]       'wdio:vscodeOptions': [Object],
[0-0]       'goog:chromeOptions': [Object]
[0-0]     },
[0-0]     firstMatch: [ {} ]
[0-0]   },
[0-0]   desiredCapabilities: {
[0-0]     browserName: 'chrome',
[0-0]     browserVersion: 'stable',
[0-0]     'wdio:vscodeOptions': {
[0-0]       extensionPath: 'path/to/extension/src',
[0-0]       userSettings: [Object],
[0-0]       binary: '"path/to/extension/.wdio-vscode-service/vscode-darwin-1.81.1/Visual Studio Code.app/Contents/MacOS/Electron"'
[0-0]     },
[0-0]     'goog:chromeOptions': {
[0-0]       binary: 'path/to/extension/node_modules/wdio-vscode-service/dist/chromium/index.js',
[0-0]       args: [Array],
[0-0]       windowTypes: [Array]
[0-0]     }
[0-0]   }
[0-0] }
[0-0] 2023-08-23T19:19:17.134Z DEBUG webdriver: request failed due to response error: unknown error
[0-0] 2023-08-23T19:19:17.136Z DEBUG @wdio/utils:shim: Finished to run "after" hook in 0ms
[0-0] 2023-08-23T19:19:17.135Z ERROR webdriver: Request failed with status 500 due to unknown error: unknown error: Chrome failed to start: exited abnormally.
[0-0]   (unknown error: DevToolsActivePort file doesn't exist)
[0-0]   (The process started from chrome location path/to/extension/node_modules/wdio-vscode-service/dist/chromium/index.js is no longer running, so ChromeDriver is assuming that Chrome has crashed.)

Running the following in my terminal results in the vscode instance starting properly

path/to/extension/node_modules/wdio-vscode-service/dist/chromium/index.js --no-sandbox --disable-updates --skip-welcome --skip-release-notes --disable-workspace-trust --disable-extensions --extension-development-path=path/to/extension/src --extension-tests-path=path/to/extension/node_modules/wdio-vscode-service/dist/proxy/cjs/entry.js --user-data-dir=/var/folders/0n/p0zc4r5j4bz1f0d5br0yv_4r0000gn/T/tmp-39900-dGKExBc9UQ8a/settings --extensions-dir=/var/folders/0n/p0zc4r5j4bz1f0d5br0yv_4r0000gn/T/tmp-39900-dGKExBc9UQ8a/extensions --vscode-binary-path="path/to/extension/.wdio-vscode-service/vscode-darwin-1.81.1/Visual Studio Code.app/Contents/MacOS/Electron"

ViewItem.getActionButton/s hangs

VS Code version: 1.64.2

When using ViewItem.getActionButtons(), it just hangs, and eventually errors with:

Can't call getAttribute on element with selector ".//a[contains(@class, 'action-label') and @role='button' and @aria-label='undefined']" because element wasn't found

Here's the problem code:

for (const item of items) {
const elem = item.$((this.locatorMap.ViewSection.actionConstructor as () => string)())
const label = (
// v1.69.0 and before
await elem.getAttribute(this.locators.actionTitle)
// v1.70.0 and after
|| await item.getAttribute(this.locators.actionTitle)
)
actions.push(new ViewItemAction(this.locatorMap, elem, label, this))
}

This is the markup for the action button:

<a class="action-label icon" role="button" title="Information" tabindex="0" style="--menu-entry-icon-light:url(&quot;vscode-file://vscode-app/Users/richardwillis/Projects/badsyntax/vscode-entity-framework/icons/help_light.svg&quot;); --menu-entry-icon-dark:url(&quot;vscode-file://vscode-app/Users/richardwillis/Projects/badsyntax/vscode-entity-framework/icons/help_dark.svg&quot;);"></a>

CJS files are missing from the 5.0.0 release

I'm not able to update to 5.0.0 because the wdio-vscode-service/dist/cjs folder is missing from the 5.0.0 release:

Spec file(s): file:///Users/fabian.jakobs/Workspaces/databricks-vscode/packages/databricks-vscode/src/test/e2e/configure.e2e.ts
Error: Error: Cannot find module '/Users/fabian.jakobs/Workspaces/databricks-vscode/packages/databricks-vscode/node_modules/wdio-vscode-service/dist/cjs/index.js'

[FEATURE_REQUEST] Allow configuring `storagePath`.

Our extension stores logs in the extension logs directory provided by vscode. To pull logs for tests, we need have a reference to storagePath (which is the root directory for useDataDir, which is where vscode stores all extension logs). Ideally, we should be able to configure this for better control.

Adding a PR that does this as well. PTAL.

Debug vscode ts extension

Is there any example how to setup a vscode debug configuration to debug extension running in wdio vscode environment.
A typescript configuration example would be appreciated.

thanks

`getText` only returns text that is visible in the output view

It appears that the output view only displays log lines that fit into the window, they are not complete. It basically returns the last n log lines. This number differs based on the available space. There are two options I could think of:

  1. expand the output view to the maximum possible size, e.g.:
    Screenshot 2022-03-24 at 18 47 10
  2. capture these logs using VSCode extension APIs, maybe there is a way to monkey patch them and capture that data from there

Service fails if manifest for the version of VS Code is not available

I've just spent a couple of hours chasing around an issue with this service.

It started failing in our pipeline with the error SevereServiceError: Couldn't set up Chromedriver Couldn't fetch Chromedriver version: Unexpected token : in JSON at position 3

We test against stable (which got updated today). Turns out that the manifest for 1.74.1 (https://raw.githubusercontent.com/microsoft/vscode/1.74.1/cgmanifest.json) has not been made available yet.

Would it be possible to fallback to main (insiders) with an appropriate message under these circumstances?

cc @christian-bromann

Theia Support

Eclipse Theia is an extensible framework to develop full-fledged multi-language Cloud & Desktop IDE-like products with state-of-the-art web technology. Given it is the foundation of many other IDEs (e.g. Arduino IDE v2) this page object framework could be valuable for everyone creating their own IDE experience. It would be interesting to see if just by creating a new locator map we can re-use the same page objects here.

If we can easily support Theia we should consider re-name the service to something more general as it has not directly something to do with VSCode. Any suggestions are welcome.

cc @planger @JonasHelming

executeWorkbench() doesn't work after Open Folder is called

We've built up several test suites for our product, and our order of execution for each suite is typically always:

  1. start up the automation/open VS Code
  2. create a folder and sample files used for test projects
  3. script VS Code to open the folder which was just created
  4. run tests within the suite

We've discovered that when VS Code opens a folder, it performs some kind of reset. (and to the end user, they see a little bit of flashing when the UI resets itself)

Prior to opening a folder, executeWorkbench() works w/o any issues.

After opening a folder, executeWorkbench() ceases to work. I dug into this and the VSCode service for WDIO is using a socket to communicate with the VS Code app, and when VS Code opens a folder, the socket is closed and not reestablished. I attempted to find a fix for this myself, but wasn't able to come up with a solution.

Allow to specify additional extension paths

By default VSCode starts with a clean state, that means no extensions installed or setup. A user might want to include certain extensions to verify compatibility. For that we should allow to include additional extensions to the setup via either local path or just extension name.

Selector for input box opened with vscode.window.showInputBox

Hi there,

I am writing a test where I need to enter a string into an InputBox and press Enter but I'm stuck on how to select such element.
In the app that I am testing, the input box gets created by calling

vscode.window.showInputBox(options)

but I don't know what kind of element (and attributes such as id, css class, etc...) this command creates, so I have no idea about how to select it from my webdriverio test. Can anyone help?

Thanks

Broken selector for `workbench.getTitleBar().getItem("")`

Hi, it seems the method getItem() on TitleBar is broken. When called (with parameter 'File' in this case) I get this error

2023-06-30T16:40:31.504Z INFO webdriver: DATA {using: 'xpath', value: './/div[@aria-label=".//div[@aria-label="File"]"]'}
2023-06-30T16:40:31.543Z WARN webdriver: Request failed with status 400 due to The selector ".//div[@aria-label=".//div[@aria-label="File"]"]" used with strategy "xpath" is invalid! For more information on selectors visit the WebdriverIO docs at: https://webdriver.io/docs/selectors

The selector indeed looks wrong, I'd expect the @aria-label to contain just "File" rather than another xpath.

Other methods such as getItem() on StatusBar or even getItems() on TitleBar itself seem to work fine, only that one method causes trouble.

I'm using wdio-vscode-service version 5.1.0

InputBox clear method behavior

I'm not sure if is the expected behavior, but calling the clear method from InputBox, only clears the last character.

clear-bug

Expected behavior:
All the text of the input box should be cleared.

As a temporary workaround iterate all the characters and invoke the clear method.

  const inputBox = new InputBox(workbench.locatorMap)
  const placeholderChars = (await inputBox.getPlaceHolder()).length
  for (let index = 0; index < placeholderChars; index++) {
     await inputBox.clear()
   }

Happy to contribute with a fix if the issue is confirmed.

Thank you for such amazing tool.

Accessing the DebugToolbar via the Workbench

Hey,
inside the vscode page object docs the debug tool bar is defined, but how can I get a instance of it via the workbench?

Didn't find a example so far.

Appreciate any help!

OpenContextMenu fails on macos

element (".monaco-menu-container") still not displayed after 5000ms

I tested the same code on my linux machine with the same node version and it works correctly

macos version 13.3 (22E252)
node version v19.9.0

extension host hangs with Error: write EPIPE

Hi!
Whenever I execute our wdio tests locally on my Macbook, after a short time my extension host instance hangs and I have to force quit it.
After digging through the vscode logs, I found this error over and over again:

2022-12-22 12:54:56.068 [error] Error: write EPIPE
    at afterWriteDispatched (node:internal/stream_base_commons:160:15)
    at writeGeneric (node:internal/stream_base_commons:151:3)
    at Socket._writeGeneric (node:net:795:11)
    at Socket._write (node:net:807:8)
    at writeOrBuffer (node:internal/streams/writable:389:12)
    at _write (node:internal/streams/writable:330:10)
    at Writable.write (node:internal/streams/writable:334:10)
    at console.value (node:internal/console/constructor:286:16)
    at console.warn (node:internal/console/constructor:365:26)
    at d.error (/Users/maxkless/data/projects/nx-console/apps/vscode-e2e/.wdio-vscode-service/vscode-darwin-1.74.1/Visual Studio Code.app/Contents/Resources/app/out/vs/code/electron-main/main.js:39:2817)
    at v.error (/Users/maxkless/data/projects/nx-console/apps/vscode-e2e/.wdio-vscode-service/vscode-darwin-1.74.1/Visual Studio Code.app/Contents/Resources/app/out/vs/code/electron-main/main.js:39:4393)
    at kt.u (/Users/maxkless/data/projects/nx-console/apps/vscode-e2e/.wdio-vscode-service/vscode-darwin-1.74.1/Visual Studio Code.app/Contents/Resources/app/out/vs/code/electron-main/main.js:82:53806)
    at I.a (/Users/maxkless/data/projects/nx-console/apps/vscode-e2e/.wdio-vscode-service/vscode-darwin-1.74.1/Visual Studio Code.app/Contents/Resources/app/out/vs/code/electron-main/main.js:82:51349)
    at I.onUnexpectedError (/Users/maxkless/data/projects/nx-console/apps/vscode-e2e/.wdio-vscode-service/vscode-darwin-1.74.1/Visual Studio Code.app/Contents/Resources/app/out/vs/code/electron-main/main.js:7:249)
    at C (/Users/maxkless/data/projects/nx-console/apps/vscode-e2e/.wdio-vscode-service/vscode-darwin-1.74.1/Visual Studio Code.app/Contents/Resources/app/out/vs/code/electron-main/main.js:7:465)
    at process.<anonymous> (/Users/maxkless/data/projects/nx-console/apps/vscode-e2e/.wdio-vscode-service/vscode-darwin-1.74.1/Visual Studio Code.app/Contents/Resources/app/out/vs/code/electron-main/main.js:82:51414)
    at process.emit (node:events:538:35)
    at process._fatalException (node:internal/process/execution:167:25)

Running the extension host without wdio works perfectly fine.

This is my local VSCode version but it's been happening for a few versions:
Version: 1.74.1
Commit: 1ad8d514439d5077d2b0b7ee64d2ce82a9308e5a
Date: 2022-12-14T10:33:40.793Z
Electron: 19.1.8
Chromium: 102.0.5005.167
Node.js: 16.14.2
V8: 10.2.154.15-electron.0
OS: Darwin x64 21.6.0
Sandboxed: No

Any idea what it could be?

Running the test script doesn't seem to actually run the tests

When I run the test script (test/specs/basic.e2e.ts), I'm told the test runs, but it doesn't appear that the tests are actually running.

Steps to repro:

  1. clone wdio-vscode-service
  2. cd into wdio-vscode-service
  3. run npm install
  4. run npm run build
  5. run npm run test (or run npm run ci)

Result:
I got the following:

[0-0] RUNNING in chrome - /test/specs/basic.e2e.ts
[0-0] PASSED in chrome - /test/specs/basic.e2e.ts

Spec Files:	 1 passed, 1 total (100% completed) in 00:00:19

Expected:
I was expecting each of the tests in basic.e2e.ts to be listed. I think basic.e2e.ts has something like 48 tests in it, so I was expecting all 48 of them to be listed, and listed as passing.

  1. I then created a new test file, /test/specs/another.e2e.ts, and added the following
describe('another test suite', () => {
    it('this should pass', () => {
        expect(1).toBe(1)
    })

    it('this won\'t pass', () => {
        expect(1).toBe(2)
    })
})
  1. ran npm run build
  2. ran npm run test

Result:
I got the following:

Execution of 2 workers started at 2022-09-12T18:14:45.778Z

Found existing install in /Users/{my-user-name}/src/github.com/webdriverio-community/wdio-vscode-service/.wdio-vscode-service/vscode-darwin-1.71.0. Skipping download
[0-0] RUNNING in chrome - /test/specs/another.e2e.ts
[0-1] RUNNING in chrome - /test/specs/basic.e2e.ts
[0-1] PASSED in chrome - /test/specs/basic.e2e.ts
[0-0] PASSED in chrome - /test/specs/another.e2e.ts

Spec Files:	 2 passed, 2 total (100% completed) in 00:00:18

Expected:
Since another.e2e.ts has a test that should pass, and a test that should fail, I was expecting the results to tell me that one test passed and another failed.

I'm new to wdio-vscode-service and evaluating it, so if I'm missing a step or making a wrong assumption, please let me know.

Don't do anything if webview was opened and re-opened again

Given a user tries to open a webview and verifies that an element exists, e.g.:

    await browser.waitUntil(async () => {
      const webviews = await workbench.getAllWebviews()
      if (webviews.length === 0) {
        return false
      }
      await webviews[0].open()
      return $('#runme-examples').isExisting()
    })

If first condition was not met then it also won't get re-checked because webviews[0].open() stales as it is already within the iframe.

Proposal:

Check if browser already entered the iframe and exit method if so.

executeCommand() runs the first matching command, not the command itself

The extension I work on is pretty complicated, and has many commands. I'm attempting to automate running one of the commands but I'm finding that when the text of the command is passed to executeCommand(), a "fuzzy match" is performed and the first matching command runs, not the command I specified.

Steps to reproduce:

  1. Let's say an extension has the following commands:
    Create and Set Up Project
    Create Project
    Create Project with Boilerplate Example

  2. Type SHIFT-CMD-P and open the command palette

  3. Type, Create Project
    -> Notice how VS Code filters the commands, and how that the commands that appear are the same that are listed in step 1, and appear in the same order

  4. Now write some e2e test code, and add the following:

const workbench = await browser.getWorkbench();
const command = 'Create Project';
// await workbench.executeCommand(command);
const prompt = await workbench.openCommandPrompt();
await prompt.setText(`>${command}`);
await prompt.confirm();
  1. And now run this test and execute this code

Result:
await workbench.openCommandPrompt() opens the command palette
...and prompt.setText() sets the text to ">Create Project"
...however, this filters the list and displays all matching commands. The first command listed is "Create and Set Up Project", and when prompt.confirm() executes, the first command listed runs, which in this case is "Create and Set Up Project", not "Create Project"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.