Playwright tests work locally but fail when run in "npx playwright test" in Azure DevOps Pipelines with "error page.goto: net::ERR_CONNECTION_RESET" - automated-tests

Context:
Playwright Version: Version 1.25.0
Operating System: windows-latest
Node.js version: v16.13.1
Browser: Firefox and Chrome
Extra: Run via Azure DevOps Pipelines in the cloud. The application login starts with the app domain, then goes to Azure login domain, then returns to original domain in the login, if it matters.
What is the goal? The goal is to include our Playwright test suite running in Azure DevOps Pipeline with a trigger.
The problem: The example test suite works locally with "npx playwright test" running all tests in separate files. But in Azure Pipelines, the example test suite works only with 1 or 2 tests, eg. "npx playwright test example.spec.ts". -> If we use "npx playwright test" and run all tests in azure-pipelines.yml, 1-2 test will pass and all others will fail with usually the login failing "page.goto: net::ERR_CONNECTION_RESET" (see errors below in Azure Pipelines log) or "page.goto: NS_ERROR_NET_RESET" with Firefox. I also sometimes "get page.goto: NS_ERROR_UNKNOWN_HOST"
What I have tried already: I've tried switching from ubuntu to windows in the .yml. I've tried running with only 1 worker and with fullyParallel: false. I also limited the browsers to Chrome only or Firefox only. I have tried to find a solution online, but I haven't encoutered this specific problem.
azure-pipelines.yml
trigger:
- tests/playwright
pool:
vmImage: 'windows-latest'
steps:
- script: echo Running azure-pipelines.yml...
displayName: 'Run a one-line script'
- task: NodeTool#0
inputs:
versionSpec: '16.x'
displayName: 'nodetool 16.x'
- task: Npm#1
inputs:
command: 'ci'
- task: CmdLine#2
inputs:
script: 'npx playwright install --with-deps'
- task: CmdLine#2
inputs:
script: 'set CI=true && echo %CI% && npx playwright test'
Azure Pipelines Job log with the errors
Retry #1 ---------------------------------------------------------------------------------------
page.goto: net::ERR_CONNECTION_RESET at https://mywebsite.com
=========================== logs ===========================
navigating to "https://mywebsite.com", waiting until "load"
============================================================
6 | console.log(`beforeEach initiated, running ${testInfo.title}`);
7 | const lg = new login(page);
> 8 | await lg.loginToAppWithAllLicenses();
| ^
9 | });
10 |
at loginToAppWithAllLicenses (D:\a\1\s\pages\login.ts:13:25)
7) [chromium] › example.spec.ts:17:5 › example test suite › Check that News and Messages is present
Test timeout of 60000ms exceeded while running "beforeEach" hook.
3 | import { login } from '../pages/login';
4 |
> 5 | test.beforeEach(async ({ page }, testInfo) => {
| ^
6 | console.log(`beforeEach initiated, running ${testInfo.title}`);
7 | const lg = new login(page);
8 | await lg.loginToAppWithAllLicenses();
page.click: Target closed
An example test that can fail
import { test, expect, Page } from '#playwright/test';
import { Utils } from '../pages/utils';
import { login } from '../pages/login';
test.beforeEach(async ({ page }, testInfo) => {
console.log(`beforeEach initiated, running ${testInfo.title}`);
const lg = new login(page);
await lg.loginToAppWithAllLicenses();
});
test.describe(example test suite', () => {
test("Check that News and Messages is present", async ({ page }) => {
await page.goto('https://mywebsite.com');
// Check that News and Messages are visible to assert that page has loaded
await expect(page.locator('ls-home-news >> text=News'))
.toHaveText('News');
await expect(page.locator('ls-home-messages >> text=Messages'))
.toHaveText('Messages');
});
});
The login that is performed in beforeEach
import { chromium, Page } from '#playwright/test';
export class login {
private page: Page;
constructor(page: Page) {
this.page = page;
}
async loginToAppWithAllLicenses() {
await this.page.goto('https://mywebsite.com');
// Click div[role="button"]:has-text("Email")
await Promise.all([
this.page.waitForNavigation(),
this.page.locator('div[role="button"]:has-text("Email")').click(),
]);
// Click [placeholder="Email Address"]
await this.page.click('[placeholder="Email Address"]');
await this.page.locator('[placeholder="Email Address"]').fill('email here..');
// Click [placeholder="Password"]
await this.page.click('[placeholder="Password"]');
await this.page.locator('[placeholder="Password"]').fill('password here..');
// Click button:has-text("Sign in")
await this.page.click('button:has-text("Sign in")');
// Select company
await this.page.click('.b-number-cell');
await this.page.waitForLoadState('networkidle');
}
}
playwright.config.ts
import type { PlaywrightTestConfig } from '#playwright/test';
import { devices } from '#playwright/test';
const config: PlaywrightTestConfig = {
testDir: './tests',
timeout: 60 * 1000,
expect: {
timeout: 5000
},
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: 1,
workers: process.env.CI ? 1 : undefined,
reporter: 'html',
use: {
actionTimeout: 0,
screenshot: 'only-on-failure',
trace: 'off',
},
projects: [
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
},
},
],
outputDir: 'test-results/',
};
export default config;

I finally managed to solve this by switching the test servers to Azure. It seems that at some point, the firewall of the server where the application was running, simply didn't want to communicate anymore.
So the problem wasn't really a Playwright-problem, but a network issue caused by the server's firewall settings.
After we moved the test application to Azure, we haven't faced such issues anymore, and the code didn't change.

Related

NextAuth.js signIn() method not working using serverless-http in AWS Lambda

I am trying to deploy NextJs and NextAuth.js to AWS using CDK (Cloud Development Kit). I have cloned the NextAuth.js example project (https://github.com/nextauthjs/next-auth-example) and
installed "serverless-http" for handling the binding from Lambda to NextJs. I attempted to follow this guide https://remaster.com/blog/nextjs-lambda-serverless-framework but using AWS CDK instead of the serverless.yml file as I am integrating it with existing infrastructure.
next.config.js:
/** #type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
images: {
unoptimized: true
},
output: 'standalone'
}
module.exports = nextConfig
[...nextauth].ts (From the example but using a simple credentials provider that always resolves):
import NextAuth, { NextAuthOptions } from "next-auth"
import CredentialsProvider from "next-auth/providers/credentials";
export const authOptions: NextAuthOptions = {
providers: [
CredentialsProvider({
name: "Credentials",
credentials: {
username: { label: "Username", type: "text", placeholder: "jsmith" },
password: { label: "Password", type: "password" }
},
async authorize(credentials, req) {
return { id: "1", name: "J Smith", email: "jsmith#example.com" }
}
})
],
theme: {
colorScheme: "light",
},
callbacks: {
async jwt({ token }) {
token.userRole = "admin"
return token
},
},
}
export default NextAuth(authOptions)
server.ts:
import { NextConfig } from "next";
import NextServer from "next/dist/server/next-server";
import serverless from "serverless-http";
// #ts-ignore
import { config } from "./.next/required-server-files.json";
const nextServer = new NextServer({
hostname: "localhost",
port: 3000,
dir: __dirname,
dev: false,
conf: {
...(config as NextConfig),
},
});
export const handler = serverless(nextServer.getRequestHandler());
It is being built using the following script:
#!/bin/bash
BUILD_FOLDER=.dist
yarn build
rm -rf $BUILD_FOLDER
mv .next/standalone/ $BUILD_FOLDER/
cp -r .next/static $BUILD_FOLDER/.next
rm $BUILD_FOLDER/server.js
cp -r next.config.js $BUILD_FOLDER/
cp -r node_modules/serverless-http $BUILD_FOLDER/node_modules/serverless-http
tsc server.ts --outDir .dist --esModuleInterop true
cp -r public $BUILD_FOLDER/
This is deployed using AWS written in CDK C#. Primarily using a HttpApi and a single Lambda. Each configured as shown below:
Lambda:
var function = new Function(this, "nextjs-function", new FunctionProps
{
Code = Code.FromAsset(...".dist"),
Handler = "server.handler",
Runtime = Runtime.NODEJS_16_X,
...
Environment = new Dictionary<string, string>
{
{ "NEXTAUTH_URL", "https://myDomainName.com" },
{ "NEXTAUTH_SECRET", portalSecret },
}
});
HttpApi:
var httpApi = new HttpApi(this, "http-api", new HttpApiProps
{
DisableExecuteApiEndpoint = true,
DefaultIntegration = new HttpLambdaIntegration("nextjs-route", function),
DefaultDomainMapping = new DomainMappingOptions
{
DomainName = "myDomainName.com"
}
});
Opening the deployed webpage and clicking the "Sign In" button at the top, I get taken to /api/auth/signin?callbackUrl=%2F with a form. Without touching the credentials I click "Sign in with credentials". This results in the page reloading and nothing happening. Expected behaviour should be a session and a redirect back to the home page (/) as is happening when running it locally using either yarn dev or yarn build && yarn start.
I get no errors client/server-side thus leaving me in the dark.
I suspect that it has to do with domain configuration but I am unable to find the problem. I tested with another NextJs/NextAuth project using a AWS Cognito provider. This also had problems as when I clicked the sign in button I got an "Unexpected token" error due to the underlying signIn(...) function (from the NextAuth library) trying to parse the fetched page as JSON, which turned out to be the sign-in-page. Thus my suspicion of something domain-related.

Error on having Vitest and Firestore working inside a Sveltekit project

To be simple, having one of the 3 tests writtens in this file (npm run test) will solve my issue:
https://github.com/regnou/vitest_firebase_demo/blob/main/src/lib/firebase/firestore.test.ts
Update -- 7th June [Fail with vitest]
I am using this starter : https://github.com/jmagrippis/with-svelte
I want to do some unit testings with Firestore and Vitest.
I actually have this error (the test will fail Timeouting):
[FirebaseError: Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore] {
: 'invalid-argument',
customData: undefined,
toString: [Function (anonymous)]
}
Update -- 8th June [Demo-project to have you reproduce the issue -- Fail with vitest]
I have created a smaller project (that keep the same amount of tecnologies, aka the same package.json) to reproduce the error:
https://github.com/regnou/vitest_firebase_demo
Error: I have a Timeout.
It seems that the Firebase SDK initializes, but operations such as setDoc, addDoc... does not work.
Here is the file where I want my tests to work:
https://github.com/regnou/vitest_firebase_demo/blob/main/src/lib/firebase/firestore.test.ts
If the unit tests succeed to executes inside this demo-project, it should also work on original-project
Update -- 10th June [Fail with mocha]
I have installed mocha (to do some tests instead of vite), and followed this file:
https://github.com/firebase/quickstart-testing/blob/master/unit-test-security-rules-v9/test/firestore.spec.js
I have used also the same dependencies as the demo mentioned above:
"#/rules-unit-testing": "^2.0.1"
"firebase": "^9.1.0"
"mocha": "^8.4.0"
But it also fails when executing the tests in my project:
FirebaseError: Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore
Update -- 11th June [Fail with vitest]
What I have undestood is that:
SecurityRules testing does not works with IMPORTS (just REQUIRE)
Firebase SDK9 works with mocha, but not with vitest.
Here is the same problem, that I present in a shorter way: Do you have a simple project example that run some unit tests with Firestore SDK 9 and Vitest?
Vitest and testing firebase security rules works out of the box :)
import {
assertFails,
initializeTestEnvironment,
} from "#firebase/rules-unit-testing";
import { test } from "vitest";
import fs from "fs";
import * as firstore from "firebase/firestore";
type Interview = {
transcript?: string;
feedback?: string;
error?: string;
userID: string;
question: string;
questionID: string;
audioID: string;
extention: string;
};
/**
* NOTE: The firebase emulator must be running for the test to work. I recomend putting you rules test in a different folder
* from the rest of your code and use `vitest --dir path-to-test-dir` to seperate them.
* you can use the `firebase emulators:exec --only firestore` to create a firestore instance before running the tests and
* it will also shut down automatically,
*
*/
let testEnv = await initializeTestEnvironment({
projectId: "stst-et-interviewer-dev",
// Specifing the hub allows firebase to automagically find all other emulators
hub: {
host: "localhost",
port: 4400,
},
firestore: {
rules: fs.readFileSync("rules/firestore.rules", "utf8"),
},
});
test(" not allow you to create a document if you are not authenticated", async () => {
const rouge = testEnv.unauthenticatedContext();
const doc = firstore.doc(rouge.firestore(), "interviews/my-interview");
const data: Interview = {
userID: "I have no id",
question: "My question",
questionID: "A question id",
audioID: "lol-an-audio-id",
extention: ".flac",
};
await assertFails(firstore.setDoc(doc, data));
});

When deploying contract using hardhat to Mumbai (Polygon) the address already exists

Contract deploys to address 0x47c5e40890bcE4a473A49D7501808b9633F29782
It looks like many other contracts were deployed to the same address by other people.
Should the address of the contract not be unique or is it deterministically generated or cached somehow by hardhat?
Why would other people have deployed to the same address?
I am wondering if this is some bug with Polygon/Mumbai testnet
const { ethers } = require("hardhat");
async function main() {
const SuperMarioWorld = await ethers.getContractFactory("Rilu");
const superMarioWorld = await SuperMarioWorld.deploy("Rilu", "RILU");
await superMarioWorld.deployed();
console.log("Success contract was deployed to: ", superMarioWorld.address)
await superMarioWorld.mint("https://ipfs.io/ipfs/QmZkUCDt5CVRWQjLDyRS4c8kU6UxRNdpsjMf6vomDcd7ep")
}
// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Hardhat
module.exports = {
solidity: '0.8.4',
networks: {
mumbai: {
url: process.env.MUMBAI_RPC,
accounts: [process.env.PRIVATE_KEY],
},
},
};
.env file (no problem with sharing the private key, just one I got from vanity-eth.tk and used for testing)
PRIVATE_KEY=84874e85685c95440e51d5edacf767f952f596cca6fd3da19b90035a20f57e37
MUMBAI_RPC=https://rpc-mumbai.maticvigil.com
Output
~/g/s/b/r/nft ❯❯❯ npx hardhat run scripts/deploy.js --network mumbai ✘ 1
Compiling 12 files with 0.8.4
Compilation finished successfully
Success contract was deployed to: 0x47c5e40890bcE4a473A49D7501808b9633F29782

Deno web workers - Cannot find name "window"

I'm trying to run a Deno app with a deno_webview and an http server but for some reason I cannot run both at the same time, calling webview.run() seems to block something and I can no longer reach my http server.
In order to prevent the blocking, I'm trying running either the server or the webview in a webworker, but in both scenarios I get the same error "Cannot find name 'window'"
What is the issue here?
api.webworker.ts
import { Application } from 'https://deno.land/x/oak/mod.ts';
const app = new Application();
await app.listen({ port: 8080 });
webview.webworker.ts
import { WebView } from 'https://deno.land/x/webview/mod.ts';
const webview = new WebView({ url: 'http://localhost:4200' });
await webview.run();
server.ts
const webviewWorker = new Worker(
'./workers/webview.worker.ts', {
type: 'module',
deno: true
});
Error:
const apiWorker = new Worker(
'./workers/api.worker.ts', {
type: 'module',
deno: true
});
Error:
Web Workers don't have window object, you have to use self or globalThis
So https://deno.land/x/webview/mod.ts doesn't support being called from a Web Worker.
The library will need to change window usage to globalThis so it will work int the main process and inside workers.

Deno run is not working properly also drun

After created an index.ts and wrote a simple code for listening to port 3000 and printing hello world on the body, I'm also not able to run or get the output from deno's drun module.
import { Application, Router } from "https://deno.land/x/denotrain#v0.5.0/mod.ts";
const app = new Application();
const router = new Router();
// Middleware
app.use((ctx) => {
ctx.cookies["user.session"] = "qwertz";
ctx.cookies["a"] = "123";
ctx.cookies["b"] = "456";
delete ctx.cookies["user.session"];
return;
});
router.get("/", (ctx) => {
return new Promise((resolve) => resolve("This is the admin interface!"));
});
router.get("/edit", async (ctx) => {
return "This is an edit mode!";
});
app.get("/", (ctx) => {
return {"hello": "world"};
});
app.use("/admin", router);
app.get("/:id", (ctx) => {
// Use url parameters
return "Hello World with ID: " + ctx.req.params.id
});
return ctx.req.body;
});
await app.run()
Development Environment:- Windows 10
The problem seems to be the address 0.0.0.0 is specific to mac only.Windows Doesn't use 0.0.0.0 address.
After going to localhost:3000 / 127.0.0.1:3000. I was able to get the output.I think maybe Windows redirects the 0.0.0.0 to localhost. Anyway it solved my problem!
I am on windows. I faced with the same problem. Then,
const app = new Application({hostname:"127.0.0.1"});
I created the app in typescript giving parameter hostname like above.
And run deno like this:
deno run --allow-net=127.0.0.1 index.ts
it worked.
Run your server with the following command:
drun watch --entryPoint=./server.ts --runtimeOptions=--allow-net
In any case most Deno tools for watching changes are still bugged, I recommend to use nodemon, with --exec flag
nodemon --exec deno run --allow-net server.ts
For convenience you can use nodemon.json with the following content:
{
"execMap": {
"js": "deno run --allow-net",
"ts": "deno run --allow-net"
},
"ext": "js,json,ts"
}
And now just use: nodemon server.ts
It seems that you have an error in your code snippet, with the last
return ctx.req.body;
});
If you fix that and use the last deno (v1.0.1) and drun(v1.1.0) versions it should works with the following command:
drun --entryPoint=index.ts --runtimeOptions=--allow-net

Resources