Skip to content

Commit

Permalink
Merge branch 'lmiller1990/windows-fails' of github.com:cypress-io/cyp…
Browse files Browse the repository at this point in the history
…ress into lmiller1990/windows-fails
  • Loading branch information
lmiller1990 committed Apr 14, 2022
2 parents d581f89 + 61cdff4 commit 6d465c8
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 3 deletions.
1 change: 1 addition & 0 deletions guides/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ For general contributor information, check out [`CONTRIBUTING.md`](../CONTRIBUTI
* [Building release artifacts](./building-release-artifacts.md)
* [Code signing](./code-signing.md)
* [Determining the next version of Cypress to be released](./next-version.md)
* [Remaining Platform Agnostic](./remaining-platform-agnostic.md)
* [Error handling](./error-handling.md)
* [Patching packages](./patch-package.md)
* [Release process](./release-process.md)
Expand Down
85 changes: 85 additions & 0 deletions guides/remaining-platform-agnostic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Remaining Platform Agnostic

Cypress works on Linux, macOS and Windows. This includes both installing from npm, as well as for local development. Code should be written in a platform agnostic style.

## Handling File Paths

Throughout the code base, we access the file system in various ways, and need be concious of how we do so to ensure Cypress can be used and developed seemlessly on multiple platforms. One thing to keep in mind is file paths and file separators. macOS and Linux systems that use `/`, and Windows which uses `\`.


As a general rule, we want to use **native paths** where possible. There are a few reasons for this. Where ever we display a file path, we want to use the native file separator, since that is what the user will expect on their platform. In general, we can use the Node.js `path` module to handle this:

```js
// on linux-like systems
path.join('cypress', 'e2e') //=> `cypress/e2e`

// on Windows
path.join('cypress', 'e2e') //=> `cypress\e2e`
```

There are some exceptions to this, namely the [`globby`](https://www.npmjs.com/package/globby) module, which only supports `/` (see [here](https://github.com/sindresorhus/globby#api)) when writing glob patterns. In these cases, where an API is posix only, you can use `path.posix.join`, which will always use `/`, even on a Windows system:

```js
// don't do
const files = await globby('my-project\cypress\e2e\**\*')

// do
const files = await globby('my-project/cypress/e2e/**/*')

// or you can convert it by splitting by path.sep
// and joining with `path.posix.join`
const glob = path.posix.join('my-project/cypress/e2e/**/*'.split(path.sep))
```

The general rule of using `path` where possible applies to moving around the file system, too:

```js
path.resolve('../', '/../', '../')
// '/home' on Linux
// '/Users' on OSX
// 'C:\\Users' on Windows
```

In general, you want to avoid writing file system code using `/` and `\`, and use Node.js APIs where possible - those are cross platform and guarenteed to work.

## Use Node.js Scripts

For many developers, it's tempting to write a quick bash script to automate tasks. Maybe you'd like to delete all `.js` files, so you add a script to `package.json`:

```json
{
"scripts": {
"clean": "rm -rf **/*.js"
}
}
```

This will stop developers on windows from running `yarn clean`. Instead, opt for a Node.js script where possible, or use a cross-platform Node.js module. In this case, we could use the [`rimraf`](https://www.npmjs.com/package/rimraf) module:

```json
{
"devDependencies": {
"rimraf": "3.0.2",
},
"scripts": {
"clean": "rimraf '**/*.js'"
}
}
```

Now your script is cross-platform.

## Use the os Module

You can use the `os` module to handle platform differences. One such example is line endings; `\n` on linux systems, and `\r\n` on Windows. Instead. use `os.EOL`. To check the current platform, use `os.arch()`:

```ts
import os from 'os'

os.EOL // \n on linux, \r\n on windows

os.platform()
// 'linux' on Linux
// 'win32' on Windows (32-bit / 64-bit)
// 'darwin' on OSX
```
6 changes: 6 additions & 0 deletions packages/app/cypress/e2e/runner/retries.mochaEvents.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ import { runSpec } from './support/spec-loader'
import { runCypressInCypressMochaEventsTest } from './support/mochaEventsUtils'
import { snapshots } from './retries.mochaEvents.snapshots'

/**
* These tests are slow, particular slow on windows, thus the
* 7500m timeout.
* TODO: Find out if they are objectively slower on windows than on linux,
* and if it's a 10.x specific performance regression.
*/
describe('src/cypress/runner retries mochaEvents', { retries: 0, defaultCommandTimeout: 7500 }, () => {
// NOTE: for test-retries

Expand Down
6 changes: 3 additions & 3 deletions packages/data-context/src/sources/GitDataSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ const GIT_LOG_COMMAND = `git log -1 --pretty="format:%ci %ar %an"`
const GIT_ROOT_DIR_COMMAND = '--show-toplevel'
const SIXTY_SECONDS = 60 * 1000

function normalize (file: string) {
return file.replace(/\\/g, '/') // normalize \ to /
function ensurePosixPathSeparators (text: string) {
return text.replace(/\\/g, '/') // normalize \ to /
}
export interface GitInfo {
author: string | null
Expand Down Expand Up @@ -320,7 +320,7 @@ export class GitDataSource {
const cmd = `FOR %x in (${paths}) DO (${GIT_LOG_COMMAND} %x)`
const result = await execa(cmd, { shell: true, cwd: this.config.projectRoot })

const stdout = normalize(result.stdout).split('\r\n') // windows uses CRLF for carriage returns
const stdout = ensurePosixPathSeparators(result.stdout).split('\r\n') // windows uses CRLF for carriage returns

const output: string[] = []

Expand Down

3 comments on commit 6d465c8

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 6d465c8 Apr 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the linux x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.0.0/linux-x64/lmiller1990/windows-fails-6d465c809cb6c847d103449d38e0c9dc00d0477a/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 6d465c8 Apr 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the darwin x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.0.0/darwin-x64/lmiller1990/windows-fails-6d465c809cb6c847d103449d38e0c9dc00d0477a/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 6d465c8 Apr 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the win32 x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.0.0/win32-x64/lmiller1990/windows-fails-6d465c809cb6c847d103449d38e0c9dc00d0477a/cypress.tgz

Please sign in to comment.