From b1b40ab1a24b0f31d788a004880c311bf52b8ea9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ant=C3=B3n=20Molleda?=
Date: Thu, 4 Nov 2021 10:37:44 -0700
Subject: [PATCH] chore: fix sidebars
---
docs/latest/README.md | 3 +-
docs/latest/api/app.md | 8 +-
docs/latest/api/browser-window.md | 2 +-
docs/latest/api/clipboard.md | 2 +-
docs/latest/tutorial/accessibility.md | 49 +++-
.../automated-testing-with-a-custom-driver.md | 142 +++++++++
docs/latest/tutorial/automated-testing.md | 272 ------------------
.../tutorial/using-selenium-and-webdriver.md | 180 ++++++++++++
scripts/tasks/update-versions-info.js | 5 +-
scripts/utils/git-commands.js | 2 +-
sidebars.js | 3 +-
versions-info.json | 7 +-
12 files changed, 389 insertions(+), 286 deletions(-)
create mode 100644 docs/latest/tutorial/automated-testing-with-a-custom-driver.md
delete mode 100644 docs/latest/tutorial/automated-testing.md
create mode 100644 docs/latest/tutorial/using-selenium-and-webdriver.md
diff --git a/docs/latest/README.md b/docs/latest/README.md
index f5275f947..8418c360e 100644
--- a/docs/latest/README.md
+++ b/docs/latest/README.md
@@ -66,9 +66,10 @@ an issue:
* [Testing and Debugging](latest/tutorial/application-debugging.md)
* [Debugging the Main Process](latest/tutorial/debugging-main-process.md)
* [Debugging with Visual Studio Code](latest/tutorial/debugging-vscode.md)
+ * [Using Selenium and WebDriver](latest/tutorial/using-selenium-and-webdriver.md)
* [Testing on Headless CI Systems (Travis, Jenkins)](latest/tutorial/testing-on-headless-ci.md)
* [DevTools Extension](latest/tutorial/devtools-extension.md)
- * [Automated Testing](latest/tutorial/automated-testing.md)
+ * [Automated Testing with a Custom Driver](latest/tutorial/automated-testing-with-a-custom-driver.md)
* [REPL](latest/tutorial/repl.md)
* [Distribution](latest/tutorial/application-distribution.md)
* [Supported Platforms](latest/tutorial/support.md#supported-platforms)
diff --git a/docs/latest/api/app.md b/docs/latest/api/app.md
index e55e369db..2ac919dbf 100644
--- a/docs/latest/api/app.md
+++ b/docs/latest/api/app.md
@@ -43,10 +43,10 @@ Returns:
* `launchInfo` Recordselection
')
console.log(hasFormat)
// 'true' or 'false'
```
diff --git a/docs/latest/tutorial/accessibility.md b/docs/latest/tutorial/accessibility.md
index 6b56906ea..685d5b899 100644
--- a/docs/latest/tutorial/accessibility.md
+++ b/docs/latest/tutorial/accessibility.md
@@ -1,14 +1,55 @@
---
title: "Accessibility"
-description: "Accessibility concerns in Electron applications are similar to those of websites because they're both ultimately HTML."
+description: "Making accessible applications is important and we're happy to provide functionality to Devtron and Spectron that gives developers the opportunity to make their apps better for everyone."
slug: accessibility
hide_title: false
---
# Accessibility
+Making accessible applications is important and we're happy to provide
+functionality to [Devtron][devtron] and [Spectron][spectron] that gives
+developers the opportunity to make their apps better for everyone.
+
+---
+
Accessibility concerns in Electron applications are similar to those of
-websites because they're both ultimately HTML.
+websites because they're both ultimately HTML. With Electron apps, however,
+you can't use the online resources for accessibility audits because your app
+doesn't have a URL to point the auditor to.
+
+These features bring those auditing tools to your Electron app. You can
+choose to add audits to your tests with Spectron or use them within DevTools
+with Devtron. Read on for a summary of the tools.
+
+## Spectron
+
+In the testing framework Spectron, you can now audit each window and ``
+tag in your application. For example:
+
+```javascript
+app.client.auditAccessibility().then(function (audit) {
+ if (audit.failed) {
+ console.error(audit.message)
+ }
+})
+```
+
+You can read more about this feature in [Spectron's documentation][spectron-a11y].
+
+## Devtron
+
+In Devtron, there is an accessibility tab which will allow you to audit a
+page in your app, sort and filter the results.
+
+![devtron screenshot][devtron-screenshot]
+
+Both of these tools are using the [Accessibility Developer Tools][a11y-devtools]
+library built by Google for Chrome. You can learn more about the accessibility
+audit rules this library uses on that [repository's wiki][a11y-devtools-wiki].
+
+If you know of other great accessibility tools for Electron, add them to the
+accessibility documentation with a pull request.
## Manually enabling accessibility features
@@ -50,6 +91,10 @@ CFStringRef kAXManualAccessibility = CFSTR("AXManualAccessibility");
}
```
+[devtron]: https://electronjs.org/devtron
+[devtron-screenshot]: https://cloud.githubusercontent.com/assets/1305617/17156618/9f9bcd72-533f-11e6-880d-389115f40a2a.png
+[spectron]: https://electronjs.org/spectron
+[spectron-a11y]: https://github.com/electron/spectron#accessibility-testing
[a11y-docs]: https://www.chromium.org/developers/design-documents/accessibility#TOC-How-Chrome-detects-the-presence-of-Assistive-Technology
[a11y-devtools]: https://github.com/GoogleChrome/accessibility-developer-tools
[a11y-devtools-wiki]: https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules
diff --git a/docs/latest/tutorial/automated-testing-with-a-custom-driver.md b/docs/latest/tutorial/automated-testing-with-a-custom-driver.md
new file mode 100644
index 000000000..ea5263dc8
--- /dev/null
+++ b/docs/latest/tutorial/automated-testing-with-a-custom-driver.md
@@ -0,0 +1,142 @@
+---
+title: "Automated Testing with a Custom Driver"
+description: "To write automated tests for your Electron app, you will need a way to \"drive\" your application. Spectron is a commonly-used solution which lets you emulate user actions via WebDriver. However, it's also possible to write your own custom driver using node's builtin IPC-over-STDIO. The benefit of a custom driver is that it tends to require less overhead than Spectron, and lets you expose custom methods to your test suite."
+slug: automated-testing-with-a-custom-driver
+hide_title: false
+---
+
+# Automated Testing with a Custom Driver
+
+To write automated tests for your Electron app, you will need a way to "drive" your application. [Spectron](https://electronjs.org/spectron) is a commonly-used solution which lets you emulate user actions via [WebDriver](https://webdriver.io/). However, it's also possible to write your own custom driver using node's builtin IPC-over-STDIO. The benefit of a custom driver is that it tends to require less overhead than Spectron, and lets you expose custom methods to your test suite.
+
+To create a custom driver, we'll use Node.js' [child_process](https://nodejs.org/api/child_process.html) API. The test suite will spawn the Electron process, then establish a simple messaging protocol:
+
+```js
+const childProcess = require('child_process')
+const electronPath = require('electron')
+
+// spawn the process
+const env = { /* ... */ }
+const stdio = ['inherit', 'inherit', 'inherit', 'ipc']
+const appProcess = childProcess.spawn(electronPath, ['./app'], { stdio, env })
+
+// listen for IPC messages from the app
+appProcess.on('message', (msg) => {
+ // ...
+})
+
+// send an IPC message to the app
+appProcess.send({ my: 'message' })
+```
+
+From within the Electron app, you can listen for messages and send replies using the Node.js [process](https://nodejs.org/api/process.html) API:
+
+```js
+// listen for IPC messages from the test suite
+process.on('message', (msg) => {
+ // ...
+})
+
+// send an IPC message to the test suite
+process.send({ my: 'message' })
+```
+
+We can now communicate from the test suite to the Electron app using the `appProcess` object.
+
+For convenience, you may want to wrap `appProcess` in a driver object that provides more high-level functions. Here is an example of how you can do this:
+
+```js
+class TestDriver {
+ constructor ({ path, args, env }) {
+ this.rpcCalls = []
+
+ // start child process
+ env.APP_TEST_DRIVER = 1 // let the app know it should listen for messages
+ this.process = childProcess.spawn(path, args, { stdio: ['inherit', 'inherit', 'inherit', 'ipc'], env })
+
+ // handle rpc responses
+ this.process.on('message', (message) => {
+ // pop the handler
+ const rpcCall = this.rpcCalls[message.msgId]
+ if (!rpcCall) return
+ this.rpcCalls[message.msgId] = null
+ // reject/resolve
+ if (message.reject) rpcCall.reject(message.reject)
+ else rpcCall.resolve(message.resolve)
+ })
+
+ // wait for ready
+ this.isReady = this.rpc('isReady').catch((err) => {
+ console.error('Application failed to start', err)
+ this.stop()
+ process.exit(1)
+ })
+ }
+
+ // simple RPC call
+ // to use: driver.rpc('method', 1, 2, 3).then(...)
+ async rpc (cmd, ...args) {
+ // send rpc request
+ const msgId = this.rpcCalls.length
+ this.process.send({ msgId, cmd, args })
+ return new Promise((resolve, reject) => this.rpcCalls.push({ resolve, reject }))
+ }
+
+ stop () {
+ this.process.kill()
+ }
+}
+```
+
+In the app, you'd need to write a simple handler for the RPC calls:
+
+```js
+if (process.env.APP_TEST_DRIVER) {
+ process.on('message', onMessage)
+}
+
+async function onMessage ({ msgId, cmd, args }) {
+ let method = METHODS[cmd]
+ if (!method) method = () => new Error('Invalid method: ' + cmd)
+ try {
+ const resolve = await method(...args)
+ process.send({ msgId, resolve })
+ } catch (err) {
+ const reject = {
+ message: err.message,
+ stack: err.stack,
+ name: err.name
+ }
+ process.send({ msgId, reject })
+ }
+}
+
+const METHODS = {
+ isReady () {
+ // do any setup needed
+ return true
+ }
+ // define your RPC-able methods here
+}
+```
+
+Then, in your test suite, you can use your test-driver as follows:
+
+```js
+const test = require('ava')
+const electronPath = require('electron')
+
+const app = new TestDriver({
+ path: electronPath,
+ args: ['./app'],
+ env: {
+ NODE_ENV: 'test'
+ }
+})
+test.before(async t => {
+ await app.isReady
+})
+test.after.always('cleanup', async t => {
+ await app.stop()
+})
+```
diff --git a/docs/latest/tutorial/automated-testing.md b/docs/latest/tutorial/automated-testing.md
deleted file mode 100644
index 1d6cfc6a5..000000000
--- a/docs/latest/tutorial/automated-testing.md
+++ /dev/null
@@ -1,272 +0,0 @@
----
-title: "Automated Testing"
-description: "Test automation is an efficient way of validating that your application code works as intended. While Electron doesn't actively maintain its own testing solution, this guide will go over a couple ways you can run end-to-end automated tests on your Electron app."
-slug: automated-testing
-hide_title: false
----
-
-# Automated Testing
-
-Test automation is an efficient way of validating that your application code works as intended.
-While Electron doesn't actively maintain its own testing solution, this guide will go over a couple
-ways you can run end-to-end automated tests on your Electron app.
-
-## Using the WebDriver interface
-
-From [ChromeDriver - WebDriver for Chrome][chrome-driver]:
-
-> WebDriver is an open source tool for automated testing of web apps across many
-> browsers. It provides capabilities for navigating to web pages, user input,
-> JavaScript execution, and more. ChromeDriver is a standalone server which
-> implements WebDriver's wire protocol for Chromium. It is being developed by
-> members of the Chromium and WebDriver teams.
-
-There are a few ways that you can set up testing using WebDriver.
-
-### With WebdriverIO
-
-[WebdriverIO](https://webdriver.io/) (WDIO) is a test automation framework that provides a
-Node.js package for testing with WebDriver. Its ecosystem also includes various plugins
-(e.g. reporter and services) that can help you put together your test setup.
-
-#### Install the testrunner
-
-First you need to run the WebdriverIO starter toolkit in your project root directory:
-
-```sh npm2yarn
-npx wdio . --yes
-```
-
-This installs all necessary packages for you and generates a `wdio.conf.js` configuration file.
-
-#### Connect WDIO to your Electron app
-
-Update the capabilities in your configuration file to point to your Electron app binary:
-
-```javascript title='wdio.conf.js'
-export.config = {
- // ...
- capabilities: [{
- browserName: 'chrome',
- 'goog:chromeOptions': {
- binary: '/path/to/your/electron/binary', // Path to your Electron binary.
- args: [/* cli arguments */] // Optional, perhaps 'app=' + /path/to/your/app/
- }
- }]
- // ...
-}
-```
-
-#### Run your tests
-
-To run your tests:
-
-```sh
-$ npx wdio run wdio.conf.js
-```
-
-[chrome-driver]: https://sites.google.com/chromium.org/driver/
-
-### With Selenium
-
-[Selenium](https://www.selenium.dev/) is a web automation framework that
-exposes bindings to WebDriver APIs in many languages. Their Node.js bindings
-are available under the `selenium-webdriver` package on NPM.
-
-#### Run a ChromeDriver server
-
-In order to use Selenium with Electron, you need to download the `electron-chromedriver`
-binary, and run it:
-
-```sh npm2yarn
-npm install --save-dev electron-chromedriver
-./node_modules/.bin/chromedriver
-Starting ChromeDriver (v2.10.291558) on port 9515
-Only local connections are allowed.
-```
-
-Remember the port number `9515`, which will be used later.
-
-#### Connect Selenium to ChromeDriver
-
-Next, install Selenium into your project:
-
-```sh npm2yarn
-npm install --save-dev selenium-webdriver
-```
-
-Usage of `selenium-webdriver` with Electron is the same as with
-normal websites, except that you have to manually specify how to connect
-ChromeDriver and where to find the binary of your Electron app:
-
-```js title='test.js'
-const webdriver = require('selenium-webdriver')
-const driver = new webdriver.Builder()
- // The "9515" is the port opened by ChromeDriver.
- .usingServer('http://localhost:9515')
- .withCapabilities({
- 'goog:chromeOptions': {
- // Here is the path to your Electron binary.
- binary: '/Path-to-Your-App.app/Contents/MacOS/Electron'
- }
- })
- .forBrowser('chrome') // note: use .forBrowser('electron') for selenium-webdriver <= 3.6.0
- .build()
-driver.get('http://www.google.com')
-driver.findElement(webdriver.By.name('q')).sendKeys('webdriver')
-driver.findElement(webdriver.By.name('btnG')).click()
-driver.wait(() => {
- return driver.getTitle().then((title) => {
- return title === 'webdriver - Google Search'
- })
-}, 1000)
-driver.quit()
-```
-
-## Using a custom test driver
-
-It's also possible to write your own custom driver using Node.js' built-in IPC-over-STDIO.
-Custom test drivers require you to write additional app code, but have lower overhead and let you
-expose custom methods to your test suite.
-
-To create a custom driver, we'll use Node.js' [`child_process`](https://nodejs.org/api/child_process.html) API.
-The test suite will spawn the Electron process, then establish a simple messaging protocol:
-
-```js title='testDriver.js'
-const childProcess = require('child_process')
-const electronPath = require('electron')
-
-// spawn the process
-const env = { /* ... */ }
-const stdio = ['inherit', 'inherit', 'inherit', 'ipc']
-const appProcess = childProcess.spawn(electronPath, ['./app'], { stdio, env })
-
-// listen for IPC messages from the app
-appProcess.on('message', (msg) => {
- // ...
-})
-
-// send an IPC message to the app
-appProcess.send({ my: 'message' })
-```
-
-From within the Electron app, you can listen for messages and send replies using the Node.js
-[`process`](https://nodejs.org/api/process.html) API:
-
-```js title='main.js'
-// listen for messages from the test suite
-process.on('message', (msg) => {
- // ...
-})
-
-// send a message to the test suite
-process.send({ my: 'message' })
-```
-
-We can now communicate from the test suite to the Electron app using the `appProcess` object.
-
-For convenience, you may want to wrap `appProcess` in a driver object that provides more
-high-level functions. Here is an example of how you can do this. Let's start by creating
-a `TestDriver` class:
-
-```js title='testDriver.js'
-class TestDriver {
- constructor ({ path, args, env }) {
- this.rpcCalls = []
-
- // start child process
- env.APP_TEST_DRIVER = 1 // let the app know it should listen for messages
- this.process = childProcess.spawn(path, args, { stdio: ['inherit', 'inherit', 'inherit', 'ipc'], env })
-
- // handle rpc responses
- this.process.on('message', (message) => {
- // pop the handler
- const rpcCall = this.rpcCalls[message.msgId]
- if (!rpcCall) return
- this.rpcCalls[message.msgId] = null
- // reject/resolve
- if (message.reject) rpcCall.reject(message.reject)
- else rpcCall.resolve(message.resolve)
- })
-
- // wait for ready
- this.isReady = this.rpc('isReady').catch((err) => {
- console.error('Application failed to start', err)
- this.stop()
- process.exit(1)
- })
- }
-
- // simple RPC call
- // to use: driver.rpc('method', 1, 2, 3).then(...)
- async rpc (cmd, ...args) {
- // send rpc request
- const msgId = this.rpcCalls.length
- this.process.send({ msgId, cmd, args })
- return new Promise((resolve, reject) => this.rpcCalls.push({ resolve, reject }))
- }
-
- stop () {
- this.process.kill()
- }
-}
-
-module.exports = { TestDriver };
-```
-
-In your app code, can then write a simple handler to receive RPC calls:
-
-```js title='main.js'
-const METHODS = {
- isReady () {
- // do any setup needed
- return true
- }
- // define your RPC-able methods here
-}
-
-const onMessage = async ({ msgId, cmd, args }) => {
- let method = METHODS[cmd]
- if (!method) method = () => new Error('Invalid method: ' + cmd)
- try {
- const resolve = await method(...args)
- process.send({ msgId, resolve })
- } catch (err) {
- const reject = {
- message: err.message,
- stack: err.stack,
- name: err.name
- }
- process.send({ msgId, reject })
- }
-}
-
-if (process.env.APP_TEST_DRIVER) {
- process.on('message', onMessage)
-}
-```
-
-Then, in your test suite, you can use your `TestDriver` class with the test automation
-framework of your choosing. The following example uses
-[`ava`](https://www.npmjs.com/package/ava), but other popular choices like Jest
-or Mocha would work as well:
-
-```js title='test.js'
-const test = require('ava')
-const electronPath = require('electron')
-const { TestDriver } = require('./testDriver')
-
-const app = new TestDriver({
- path: electronPath,
- args: ['./app'],
- env: {
- NODE_ENV: 'test'
- }
-})
-test.before(async t => {
- await app.isReady
-})
-test.after.always('cleanup', async t => {
- await app.stop()
-})
-```
diff --git a/docs/latest/tutorial/using-selenium-and-webdriver.md b/docs/latest/tutorial/using-selenium-and-webdriver.md
new file mode 100644
index 000000000..721209ad6
--- /dev/null
+++ b/docs/latest/tutorial/using-selenium-and-webdriver.md
@@ -0,0 +1,180 @@
+---
+title: "Selenium and WebDriver"
+description: "From ChromeDriver - WebDriver for Chrome:"
+slug: using-selenium-and-webdriver
+hide_title: false
+---
+
+# Selenium and WebDriver
+
+From [ChromeDriver - WebDriver for Chrome][chrome-driver]:
+
+> WebDriver is an open source tool for automated testing of web apps across many
+> browsers. It provides capabilities for navigating to web pages, user input,
+> JavaScript execution, and more. ChromeDriver is a standalone server which
+> implements WebDriver's wire protocol for Chromium. It is being developed by
+> members of the Chromium and WebDriver teams.
+
+## Setting up Spectron
+
+[Spectron][spectron] is the officially supported ChromeDriver testing framework
+for Electron. It is built on top of [WebdriverIO](https://webdriver.io/) and
+has helpers to access Electron APIs in your tests and bundles ChromeDriver.
+
+```sh
+$ npm install --save-dev spectron
+```
+
+```javascript
+// A simple test to verify a visible window is opened with a title
+const Application = require('spectron').Application
+const assert = require('assert')
+
+const myApp = new Application({
+ path: '/Applications/MyApp.app/Contents/MacOS/MyApp'
+})
+
+const verifyWindowIsVisibleWithTitle = async (app) => {
+ await app.start()
+ try {
+ // Check if the window is visible
+ const isVisible = await app.browserWindow.isVisible()
+ // Verify the window is visible
+ assert.strictEqual(isVisible, true)
+ // Get the window's title
+ const title = await app.client.getTitle()
+ // Verify the window's title
+ assert.strictEqual(title, 'My App')
+ } catch (error) {
+ // Log any failures
+ console.error('Test failed', error.message)
+ }
+ // Stop the application
+ await app.stop()
+}
+
+verifyWindowIsVisibleWithTitle(myApp)
+```
+
+## Setting up with WebDriverJs
+
+[WebDriverJs](https://www.selenium.dev/selenium/docs/api/javascript/index.html) provides
+a Node package for testing with web driver, we will use it as an example.
+
+### 1. Start ChromeDriver
+
+First you need to download the `chromedriver` binary, and run it:
+
+```sh
+$ npm install electron-chromedriver
+$ ./node_modules/.bin/chromedriver
+Starting ChromeDriver (v2.10.291558) on port 9515
+Only local connections are allowed.
+```
+
+Remember the port number `9515`, which will be used later
+
+### 2. Install WebDriverJS
+
+```sh
+$ npm install selenium-webdriver
+```
+
+### 3. Connect to ChromeDriver
+
+The usage of `selenium-webdriver` with Electron is the same with
+upstream, except that you have to manually specify how to connect
+chrome driver and where to find Electron's binary:
+
+```javascript
+const webdriver = require('selenium-webdriver')
+
+const driver = new webdriver.Builder()
+ // The "9515" is the port opened by chrome driver.
+ .usingServer('http://localhost:9515')
+ .withCapabilities({
+ 'goog:chromeOptions': {
+ // Here is the path to your Electron binary.
+ binary: '/Path-to-Your-App.app/Contents/MacOS/Electron'
+ }
+ })
+ .forBrowser('chrome') // note: use .forBrowser('electron') for selenium-webdriver <= 3.6.0
+ .build()
+
+driver.get('http://www.google.com')
+driver.findElement(webdriver.By.name('q')).sendKeys('webdriver')
+driver.findElement(webdriver.By.name('btnG')).click()
+driver.wait(() => {
+ return driver.getTitle().then((title) => {
+ return title === 'webdriver - Google Search'
+ })
+}, 1000)
+
+driver.quit()
+```
+
+## Setting up with WebdriverIO
+
+[WebdriverIO](https://webdriver.io/) provides a Node package for testing with web
+driver.
+
+### 1. Start ChromeDriver
+
+First you need to download the `chromedriver` binary, and run it:
+
+```sh
+$ npm install electron-chromedriver
+$ ./node_modules/.bin/chromedriver --url-base=wd/hub --port=9515
+Starting ChromeDriver (v2.10.291558) on port 9515
+Only local connections are allowed.
+```
+
+Remember the port number `9515`, which will be used later
+
+### 2. Install WebdriverIO
+
+```sh
+$ npm install webdriverio
+```
+
+### 3. Connect to chrome driver
+
+```javascript
+const webdriverio = require('webdriverio')
+const options = {
+ host: 'localhost', // Use localhost as chrome driver server
+ port: 9515, // "9515" is the port opened by chrome driver.
+ desiredCapabilities: {
+ browserName: 'chrome',
+ 'goog:chromeOptions': {
+ binary: '/Path-to-Your-App/electron', // Path to your Electron binary.
+ args: [/* cli arguments */] // Optional, perhaps 'app=' + /path/to/your/app/
+ }
+ }
+}
+
+const client = webdriverio.remote(options)
+
+client
+ .init()
+ .url('http://google.com')
+ .setValue('#q', 'webdriverio')
+ .click('#btnG')
+ .getTitle().then((title) => {
+ console.log('Title was: ' + title)
+ })
+ .end()
+```
+
+## Workflow
+
+To test your application without rebuilding Electron,
+[place](latest/tutorial/application-distribution.md)
+your app source into Electron's resource directory.
+
+Alternatively, pass an argument to run with your Electron binary that points to
+your app's folder. This eliminates the need to copy-paste your app into
+Electron's resource directory.
+
+[chrome-driver]: https://sites.google.com/a/chromium.org/chromedriver/
+[spectron]: https://electronjs.org/spectron
diff --git a/scripts/tasks/update-versions-info.js b/scripts/tasks/update-versions-info.js
index be3acc799..a6933c824 100644
--- a/scripts/tasks/update-versions-info.js
+++ b/scripts/tasks/update-versions-info.js
@@ -24,18 +24,21 @@ const createVersionEntry = (options) => {
*/
const updateVersionsInfo = async (latest) => {
const current = await getCurrentBranchName();
- const versions = [createVersionEntry({ label: latest, version: 'latest' })];
+ const versions = [];
if (!/v\d+-x-y/.test(current)) {
const branches = await getRemoteBranches();
const tracked = branches
.map((branch) => branch.split('/').pop())
+ .reverse()
.filter((branch) => /v\d+-x-y/.test(branch))
.map((version) => createVersionEntry({ version }));
versions.push(...tracked);
}
+ versions.unshift(createVersionEntry({ label: latest, version: 'latest' }));
+
await fs.writeFile(VERSIONS_INFO, JSON.stringify(versions, null, 2), 'utf-8');
};
diff --git a/scripts/utils/git-commands.js b/scripts/utils/git-commands.js
index 6c21176e2..43e0b593b 100644
--- a/scripts/utils/git-commands.js
+++ b/scripts/utils/git-commands.js
@@ -127,7 +127,7 @@ const getRemoteBranches = async () => {
const branches = stdout
.split('\n')
.map((line) => line.trim())
- .filter((line) => !line.includes('->'));
+ .filter((line) => !line.includes('->') && line.startsWith('origin'));
return branches;
};
diff --git a/sidebars.js b/sidebars.js
index 891e0b787..dfd3b4264 100644
--- a/sidebars.js
+++ b/sidebars.js
@@ -37,8 +37,7 @@ module.exports = {
'latest/tutorial/windows-arm',
'latest/tutorial/windows-taskbar',
'latest/tutorial/tray',
- 'latest/tutorial/window-customization',
- 'latest/tutorial/automated-testing',
+ 'latest/tutorial/window-customization'
],
},
{
diff --git a/versions-info.json b/versions-info.json
index e7239537d..148b3736c 100644
--- a/versions-info.json
+++ b/versions-info.json
@@ -1,7 +1,12 @@
[
{
- "label": "15-x-y",
+ "label": "Latest",
"href": "https://electronjs.org/docs/latest",
"target": "_blank"
+ },
+ {
+ "label": "v14-x-y",
+ "href": "https://electronjs.org/docs/v14-x-y",
+ "target": "_blank"
}
]
\ No newline at end of file