Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: update dependency @elastic/synthetics and Playwright #285

Merged
merged 12 commits into from
Aug 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .ci/scripts/run-test-in-docker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ fi
docker run \
$DOCKER_RUN_OPTIONS \
-u '0:0' \
-v "$(pwd):/synthetics-recorder" \
-e NPM_COMMAND=${1:-''} \
$DOCKER_IMAGE \
.ci/scripts/run-test.sh
2 changes: 1 addition & 1 deletion .ci/scripts/run-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ set -x
if [ -n "${NPM_COMMAND}" ] ; then
npm ${NPM_COMMAND}
fi
NPM_CONFIG_LOGLEVEL=verbose npm test
NPM_CONFIG_LOGLEVEL=verbose npm run test
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ module.exports = {
rules: {
'@typescript-eslint/explicit-module-boundary-types': 0,
'@typescript-eslint/no-non-null-assertion': 0,
'@typescript-eslint/no-explicit-any': 0,
},
},
],
Expand Down
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
package-lock=true
engine-strict=true
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=true
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v14.17.5
v16.15.0
102 changes: 40 additions & 62 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,6 @@ You can find downloadable installers there for a variety of platforms.

Download and unpack the appropriate installer for your platform, and install it.

#### Possible install issues

If you receive a set of error logs like those listed below, it is likely because your
version of `npm` is higher than `v6`. Later versions of `npm` are stricter about peer
dependency resolution, and thus it will refuse to install.

```
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: [email protected]
npm ERR! Found: @types/[email protected]
npm ERR! node_modules/@types/react-dom
npm ERR! dev @types/react-dom@"^17.0.10" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer @types/react-dom@"^16.9.6" from @elastic/[email protected]
npm ERR! node_modules/@elastic/eui
npm ERR! @elastic/eui@"^37.0.0" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
```

You can get around this by using `npm` version 6 to install.

#### Usage

Expand Down Expand Up @@ -84,51 +58,55 @@ Run the recorder app in dev mode.
npm run dev
```

### Troubleshooting
#### Managing Playwright dependency
When updating the version of [@elastic/synthetics](https://github.com/elastic/synthetics)(called _Synthetics agent_ hereafter), it is important to align the version of Playwright that the Synthetics agent uses and the forked Playwright that is installed by the recorder. Steps to update the Playwright is as followed:

#### Page object is not defined
1. Go to [@elastic/playwright](https://github.com/elastic/playwright), fetch upstream microsoft:main into main if needed. We keep our modifications in `synthetics-recorder` branch. It is supposed to have only one extra commit[(84309bf)](https://github.com/elastic/playwright/commit/84309bf44d2a97889b178f2f2da2bc9f30e5aff8)) compared to the main branch. If main branch has new commits, fetch the changes into `synthetics-recorder` branch by pulling it with [rebase](https://git-scm.com/docs/git-pull#Documentation/git-pull.txt---rebasefalsetruemergesinteractive) option

It is possible to define a series of steps that splits your recorded actions in a way that causes the required
page object to be out of scope. You may be encountering this issue if, when testing or running your journey, you
see an error message like:

```javascript
page1 is not defined
1. Pull the remote changes to your machine. If necessary, set the remote as follows:
```

You can verify the problem by clicking the `Export` button in the recorder and checking the code output. If your generated
code is similar to the example below, you may need to rearrange your steps.

```javascript
step('Click text=Babel Minify', async () => {
// `page2` is defined here
const [page2] = await Promise.all([page.waitForEvent('popup'), page.click('text=Babel Minify')]);
await page2.click(':nth-match(a:has-text("babel-minify"), 3)');
});
step('Close page', async () => {
// referencing `page2`, which is now out of scope
await page2.close();
});
git remote add upstream https://github.com/microsoft/playwright.git
git remote add elastic https://github.com/elastic/playwright.git
git remote -v
// prints:
// upstream https://github.com/microsoft/playwright.git (fetch)
// upstream https://github.com/microsoft/playwright.git (push)
// elastic https://github.com/elastic/playwright.git (fetch)
// elastic https://github.com/elastic/playwright.git (push)
```

By removing the second step divider in the Script Recorder UI, we will generate code that keeps the `page2` object
in scope for all its references.

```javascript
step('Click text=Babel Minify', async () => {
// now all references to `page2` occur while it is still in scope
const [page2] = await Promise.all([page.waitForEvent('popup'), page.click('text=Babel Minify')]);
await page2.click(':nth-match(a:has-text("babel-minify"), 3)');
await page2.close();
});
2. Confirm the Playwright version from Synthetics agent's `package.json`:
```
// @elastic/synthetics's package.json
...
"playwright-core": "=1.20.1",
...
```
3. Fetch the tags from upstream, checkout to the version 1.20.1, and create a new branch:
```
git fetch upstream --tags
git checkout -b 1.20.1-recorder v1.20.1
```
4. Cherry-pick the commit from `synthetics-recorder` branch, then run `npm run build`. You should see generated js files under `packages/playwright-core/lib` directory. Commit all the changes and push it to elastic remote:
```
git cherry-pick 84309bf
# solve conflicts if necessary
npm run build
git add .
git push --set-upstream elastic 1.20.1-recorder
```
5. Test new changes in the Recorder by updating Recorder's package.json. Update `playwright` dependency to the branch you pushed from above step:
```js
// @elastic/synthetics-recorder's package.json
...
"playwright": "https://gitpkg.now.sh/elastic/playwright/packages/playwright-core?1.20.1-recorder",
...
```

We are actively working on a solution to this issue, you can follow the progress [here](https://github.com/elastic/synthetics-recorder/issues/195).

For now, we are doing it all manually, However, we should consider automating the process.
### Build

Build and Package the app for all platforms

```
npm run build
npm run pack -- -mwl
```
6 changes: 3 additions & 3 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
### Releasing

**NOTE: This project is currently in Alpha phase**
**NOTE: This project is currently in Beta phase**

#### Manually

Expand All @@ -9,7 +9,7 @@ the process is as follows:

1. Be sure you have checked out the `main` branch and have pulled the latest changes
1. Run the tests to make sure everything is green
1. Bump the alpha version by running `npm version prerelease --preid=alpha`
1. Bump the beta version by running `npm version prerelease --preid=beta`
1. Run the release command using `GH_TOKEN=<token> npm run release`
1. If release is successful, push commits and tags upstream with
`git push upstream main && git push upstream --tags`
Expand All @@ -19,6 +19,6 @@ the process is as follows:
The release process is also automated in the way any specific commit from the main branch can be potentially released, for such it's required the below steps:

1. Be sure you have checked out the `main` branch and have pulled the latest changes
1. Bump the alpha version by running `npm version prerelease --preid=alpha`
1. Bump the beta version by running `npm version prerelease --preid=beta`
1. Push commits and tags upstream with `git push upstream main && git push upstream --tags`
1. Wait for an email/slack to confirm the release is done.
32 changes: 21 additions & 11 deletions common/helper/test/createAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,41 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

import { Action, Step } from '@elastic/synthetics';
import { ActionContext, RecorderSteps } from '../../types';
import { Action /* Step */ } from '@elastic/synthetics';
import { ActionContext, FrameDescription, RecorderSteps, Step } from '../../types';

type ActionOverride = Partial<Action>;
type ActionWithName = Partial<Action> & { name: string };
type CreateStepActionOverride = Partial<Omit<ActionContext, 'action'>> & { action: ActionWithName };
type ActionContextOverride = Partial<Omit<ActionContext, 'action'>> & { action?: ActionOverride };
type OptionalActionContext = Omit<ActionContext, 'action' | 'frame'>;
type ActionContextOverride = OptionalActionContext & {
frame?: Partial<FrameDescription>;
action?: Partial<Action>;
};
type CreateStepActionOverride = OptionalActionContext & {
frame?: Partial<FrameDescription>;
action: Partial<Action> & { name: string };
};

export const createAction = (name: string, overrides?: ActionContextOverride): ActionContext => {
const baseAction = {
frameUrl: 'https://www.elastic.co',
isMainFrame: true,
committed: true,
pageAlias: 'page',
frame: {
url: 'https://www.elastic.co',
isMainFrame: true,
committed: true,
pageAlias: 'page',
},
};
return overrides
? {
...baseAction,
...overrides,
action: {
name,
signals: [],
url: 'https://www.elastic.co',
...overrides.action,
},
frame: {
...baseAction.frame,
...overrides.frame,
},
}
: {
...baseAction,
Expand Down
35 changes: 27 additions & 8 deletions common/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,39 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

import type { ActionInContext, Step, Steps } from '@elastic/synthetics';
import type { /* Step, Steps, */ Action } from '@elastic/synthetics';

export type Step = {
actions: ActionInContext[];
name?: string;
};

export type Steps = Step[];

export type ActionInContext = {
frame: FrameDescription;
action: Action;
committed?: boolean;
modified?: boolean;
title?: string;
};

// from playwright-core
export type FrameDescription = {
pageAlias: string;
isMainFrame?: boolean;
url: string;
name?: string;
selectorsChain?: string[];
};
export interface ActionContext extends ActionInContext {
isOpen?: boolean;
isSoftDeleted?: boolean;
}
export interface RecorderStep<ActionType = ActionContext> extends Step {
actions: ActionType[];
}

interface RecorderSteps<StepType = RecorderStep> extends Steps {
[key: number]: StepType;
export interface RecorderStep extends Step {
actions: ActionContext[];
}

export type RecorderSteps = RecorderStep[];
export type StepStatus = 'succeeded' | 'failed' | 'skipped';
export type JourneyType = 'project' | 'inline';

Expand Down
6 changes: 3 additions & 3 deletions e2e/Dockerfile.jenkins
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ RUN apt-get -y -qq install xvfb \
ENV DISPLAY $DISPLAY
ENV NPM_COMMAND ci

COPY . ./synthetics-recorder
WORKDIR /synthetics-recorder

# Copy .nvmrc as long as you run the script in .ci/scripts/docker-build.sh
ADD .nvmrc /synthetics-recorder/.nvmrc
# ADD .nvmrc /synthetics-recorder/.nvmrc

# Installing NVM
ENV NVM_DIR /root
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
RUN source "${NVM_DIR}/nvm.sh" --install \
&& nvm use
&& nvm use && npm ci
24 changes: 12 additions & 12 deletions electron/__snapshots__/syntheticsGenerator.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ journey('Recorded journey', async ({ page, context }) => {
expect(await page.textContent('text=Babel Minify')).toMatch('Babel');
[page1] = await Promise.all([
page.waitForEvent('popup'),
page.click('text=Babel Minify')
page.locator('text=Babel Minify').click()
]);
await Promise.all([
page1.waitForNavigation({ url: 'https://github.com/babel/minify' }),
page1.click('a:has-text(\\"smoke\\")')
page1.locator('a:has-text(\\"smoke\\")').click()
]);
});
step('Close page', async () => {
Expand All @@ -36,14 +36,14 @@ step('Go to https://vigneshh.in/', async () => {
await page.goto('https://vigneshh.in/');
[page1] = await Promise.all([
page.waitForEvent('popup'),
page.click('text=Tailor')
page.locator('text=Tailor').click()
]);
await page1.click('text=Packages 0');
await page1.locator('text=Packages 0').click();
expect(page1.url()).toBe('https://github.com/orgs/zalando/packages?repo_name=tailor');
await page1.close();
[page2] = await Promise.all([
page.waitForEvent('popup'),
page.click('text=Babel Minify')
page.locator('text=Babel Minify').click()
]);
await page2.close();
});"
Expand All @@ -56,16 +56,16 @@ step('Go to https://vigneshh.in/', async () => {
await page.goto('https://vigneshh.in/');
[page1] = await Promise.all([
page.waitForEvent('popup'),
page.click('text=Tailor')
page.locator('text=Tailor').click()
]);
await page1.click('text=Packages 0');
await page1.locator('text=Packages 0').click();
expect(page1.url()).toBe('https://github.com/orgs/zalando/packages?repo_name=tailor');
});
step('Close page', async () => {
await page1.close();
[page2] = await Promise.all([
page.waitForEvent('popup'),
page.click('text=Babel Minify')
page.locator('text=Babel Minify').click()
]);
});
step('Close page', async () => {
Expand All @@ -80,9 +80,9 @@ step('Go to https://vigneshh.in/', async () => {
await page.goto('https://vigneshh.in/');
[page1] = await Promise.all([
page.waitForEvent('popup'),
page.click('text=Tailor')
page.locator('text=Tailor').click()
]);
await page1.click('text=Packages 0');
await page1.locator('text=Packages 0').click();
expect(page1.url()).toBe('https://github.com/orgs/zalando/packages?repo_name=tailor');
});
step('Close page', async () => {
Expand All @@ -91,9 +91,9 @@ step('Close page', async () => {
step('Click text=Babel Minify', async () => {
[page2] = await Promise.all([
page.waitForEvent('popup'),
page.click('text=Babel Minify')
page.locator('text=Babel Minify').click()
]);
await page2.click(':nth-match(a:has-text(\\"babel-minify\\"), 3)');
await page2.locator(':nth-match(a:has-text(\\"babel-minify\\"), 3)').click();
expect(page2.url()).toBe('https://github.com/topics/babel-minify');
});
step('Close page', async () => {
Expand Down
4 changes: 2 additions & 2 deletions electron/execution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ import { fork, ChildProcess } from 'child_process';
import logger from 'electron-log';
import isDev from 'electron-is-dev';
import { JOURNEY_DIR, PLAYWRIGHT_BROWSERS_PATH, EXECUTABLE_PATH } from './config';
import type { BrowserContext } from 'playwright';
import type { ActionInContext } from '@elastic/synthetics';
import type { BrowserContext } from 'playwright-core';
import type {
ActionInContext,
GenerateCodeOptions,
RecorderSteps,
RecordJourneyOptions,
Expand Down
Loading