Skip to content

Commit

Permalink
fix(jest-environment-puppeteer): Class & Exports (#37647)
Browse files Browse the repository at this point in the history
* fix(jest-environment-puppeteer): Class & Exports

This makes the typings actually compatible to create your own test
environment and not just as part of the bigger jest-puppeteer package.
How to do this is pretty much what the test covers. One of the reasons
to do this is to write a handler where Puppeteer takes screenshots after
each failed test, as discussed [here](argos-ci/jest-puppeteer#131)

* Change to `export =` syntax

Co-Authored-By: Pranav Senthilnathan <pranav.senthilnathan@live.com>

* Fix the last stuff requested
  • Loading branch information
favna authored and sheetalkamat committed Aug 19, 2019
1 parent bd2ed19 commit bbe8520
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 7 deletions.
46 changes: 44 additions & 2 deletions types/jest-environment-puppeteer/index.d.ts
Expand Up @@ -2,10 +2,16 @@
// Project: https://github.com/smooth-code/jest-puppeteer/tree/master/packages/jest-environment-puppeteer
// Definitions by: Josh Goldberg <https://github.com/joshuakgoldberg>
// Ifiok Jr. <https://github.com/ifiokjr>
// Jeroen Claassens <https://github.com/favna>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.8
// TypeScript Version: 3.4

import { JestEnvironment } from '@jest/environment';
import { JestFakeTimers as FakeTimers } from '@jest/fake-timers';
import { Circus, Global as GlobalType, Config } from '@jest/types';
import { ModuleMocker } from 'jest-mock';
import { Browser, Page, BrowserContext } from 'puppeteer';
import { Script, Context } from 'vm';

interface JestPuppeteer {
/**
Expand Down Expand Up @@ -44,11 +50,47 @@ interface JestPuppeteer {
debug(): Promise<void>;
}

interface Timer {
id: number;
ref: () => Timer;
unref: () => Timer;
}

interface Global extends GlobalType.Global {
browser: Browser;
context: Context;
page: Page;
jestPuppeteer: JestPuppeteer;
}

/** Note: TestEnvironment is sandboxed. Each test suite will trigger setup/teardown in their own TestEnvironment. */
declare class PuppeteerEnvironment implements JestEnvironment {

This comment has been minimized.

Copy link
@douglascayers

douglascayers Apr 19, 2020

Contributor

@favna, can you share some more details about why this implements JestEnvironment? In the jest-puppeteer package I see that it extends NodeEnvironment, not JestEnvironment.

I bring this up because I get a typescript compiler error:

Class 'PuppeteerEnvironment' incorrectly implements class 'JestEnvironment'. Did you mean to extend 'JestEnvironment' and inherit its members as a subclass?
Property 'fakeTimersLolex' is missing in type 'PuppeteerEnvironment' but required in type 'JestEnvironment'.ts(2720)

I have the following versions installed:

  • "puppeteer": "3.0.0"
  • "jest-puppeteer": "4.4.0"
  • "@types/puppeteer": "2.0.1"
  • "@types/jest-environment-puppeteer": "4.3.1"
  • "@types/expect-puppeteer": "4.4.1"

image

Thanks

This comment has been minimized.

Copy link
@favna

favna Apr 19, 2020

Author Contributor

@douglascayers been a while since I did anything Puppeteer. This looks like the typings are just outdated though. If PuppeteerEnvironment has a property of fakeTimersLolex as it should because it is implementing JestEnvironment than it should be resolved. Do you want to do this and create a PR for it?

Anyway at the time that I added these typings they worked for me. I was using latest stable releases of all relevant packages at that time (August 19th 2019), including whatever latest stable version was for TypeScript. If for any reason you want to check if it worked with those versions you can I guess, just have to find out what versions to grab for that date (npm release history is your friend there)

This comment has been minimized.

Copy link
@douglascayers

douglascayers Apr 19, 2020

Contributor

Thanks @favna for the confirmation. I’m new to puppeteer and wasn’t sure if I had missed something in my setup.

I think the typings might be outdated at this point as you suggest.

I’ll go ahead and submit a pull request later today.

Thanks!

This comment has been minimized.

Copy link
@douglascayers

douglascayers Apr 19, 2020

Contributor

Closing the loop, I've submitted #44033

context: Context | null;
fakeTimers: FakeTimers<Timer> | null;
global: Global;
moduleMocker: ModuleMocker | null;
constructor(config: Config.ProjectConfig);

/**
* Setup runs when the environment is being spun up, generally before each test suite
* You should always call `await super.setup()` in here
*/
setup(): Promise<void>;

/**
* Teardowns runs as the environment is being torn down, generally after each test suite.
* You should always call `await super.tearDown()` in here
*/
teardown(): Promise<void>;
runScript(script: Script): any;
handleTestEvent?(event: Circus.Event, state: Circus.State): void;
}

declare global {
const browser: Browser;
const context: BrowserContext;
const page: Page;
const jestPuppeteer: JestPuppeteer;
}

export {};
export = PuppeteerEnvironment;
@@ -1,8 +1,42 @@
import * as puppeteer from "puppeteer";
import { Browser, Page, BrowserContext } from 'puppeteer';
import JestEnvironmentPuppeteer from 'jest-environment-puppeteer';
import { Config, Circus } from '@jest/types';
import { Script } from 'vm';

const myBrowser: puppeteer.Browser = browser;
const myPage: puppeteer.Page = page;
const myContext: puppeteer.BrowserContext = context;
const myBrowser: Browser = browser; // $ExpectType Browser
const myPage: Page = page; // $ExpectType Page
const myContext: BrowserContext = context; // $ExpectType BrowserContext

jestPuppeteer.debug();
jestPuppeteer.resetPage();

// Creating a custom Jest environment
class CustomJestEnvironment extends JestEnvironmentPuppeteer {
constructor(config: Config.ProjectConfig) {
super(config);
}

async setup() {
await super.setup();
await this.global.page.goto('https://www.google.com');
}

async teardown() {
await this.global.page.waitFor(2000);
await super.teardown();
}

runScript(script: Script) {
return super.runScript(script);
}

async handleTestEvent(event: Circus.Event, state: Circus.State) {
if (event.name === 'test_fn_failure') {
console.error('woaw your test failed, you should feel bad!');
}
}
}

type JestEnvironmentPuppeteerGlobal = JestEnvironmentPuppeteer['global']; // $ExpectType Global
type JestEnvironmentPuppeteerGlobalPuppeteer = JestEnvironmentPuppeteer['global']['jestPuppeteer']; // $ExpectType JestPuppeteer
type JestEnvironmentPuppeteerFakeTimers = JestEnvironmentPuppeteer['fakeTimers']; // $ExpectType FakeTimers<Timer> | null
9 changes: 9 additions & 0 deletions types/jest-environment-puppeteer/package.json
@@ -0,0 +1,9 @@
{
"private": true,
"dependencies": {
"@jest/environment": "^24",
"@jest/fake-timers": "^24",
"@jest/types": "^24",
"jest-mock": "^24"
}
}
3 changes: 2 additions & 1 deletion types/jest-environment-puppeteer/tsconfig.json
Expand Up @@ -15,7 +15,8 @@
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true
},
"files": [
"index.d.ts",
Expand Down

0 comments on commit bbe8520

Please sign in to comment.