Playwright is not running tests on Selenium Grid + Docker - docker

I'm trying to run some Playwright (Node.js) tests on Docker through Selenium Grid, but the tests are failing because of timeout. Chrome is apparently not starting. Locally without Docker everything is fine.
According to the Playwright documentation, it would be enough to run the tests using the following command:
SELENIUM_REMOTE_URL=http://localhost:4444/wd/hub npx playwright test
But that is not working.
I'm building the environment in Docker by running the following file through Powershell:
$maxNodes = 1
function GetImages()
{
docker pull selenium/hub:latest
docker pull selenium/node-chrome:latest
}
function CreateGrid()
{
docker network create grid
}
function CreateHub()
{
docker run -d -p 4442-4444:4442-4444 --net grid --name hub selenium/hub:latest
}
function CreateNodes()
{
$nodes = 1
while($nodes -le $maxNodes)
{
docker run -d -P --net grid -e SE_EVENT_BUS_HOST=hub -e SE_EVENT_BUS_PUBLISH_PORT=4442 -e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 -e SE_NODE_SESSION_TIMEOUT=120 selenium/node-chrome:latest
$nodes++
}
}
cls
GetImages
CreateGrid
CreateHub
CreateNodes
cls
Write-Host "HUB AND NODES CREATED!!"
After running the tests using the above mentioned command, the result is as follows.
In Docker Selenium Grid, the following is displayed.
The session is "empty" with nothing running. The browser has a blank page.
The config from playwright.config.ts is:
import { PlaywrightTestConfig } from '#playwright/test';
const config: PlaywrightTestConfig = {
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 1 : 0,
timeout: 20000,
workers:1,
use: {
baseURL: 'https://www.google.com',
viewport: { width: 1280, height: 720 },
browserName: "chromium",
channel: "chrome",
headless: false
}
};
export default config;
And the test running is:
test('Acessar Google', async ({ page }) => {
await page.goto('/');
const length = await page.locator('input[type=submit]').count();
expect(length >= 1).toBeTruthy();
});
I don't know what could be going wrong.
Can anyone help me?

Related

No Docker client strategy found

I'm trying to implement E2E testing in NestJS application. I'm using Postgres in a docker container. It is running fine for other testing. The only problem is E2E testing. And I'm getting the following error:
No Docker client strategy found
at node_modules/testcontainers/dist/docker/docker-client.js:46:11
at fulfilled (node_modules/testcontainers/dist/docker/docker-client.js:5:58)
● Test suite failed to run
TypeError: Cannot read properties of undefined (reading 'close')
59 |
60 | afterAll(async () => {
> 61 | await app.close();
| ^
62 | await container.stop();
63 | });
64 |
at Object.<anonymous> (test/event.e2e-spec.ts:61:15)
My code is given below:
describe('EventAPI (e2e)', () => {
jest.setTimeout(180_000);
let app: INestApplication;
let service: Service;
let container: E2EPgContainer;
beforeAll(async () => {
container = new E2EPgContainer();
await container.init();
// eslint-disable-next-line #typescript-eslint/no-var-requires
const AppModule = require('../src/server/app/app.module').AppModule;
const module: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = module.createNestApplication();
app.useGlobalPipes(new ValidationPipe({ transform: true }));
service = module.get<Service>(Service);
await app.init();
});
afterEach(() => {
jest.clearAllMocks();
});
afterAll(async () => {
await app.close();
await container.stop();
});
describe('GET-POINT API', () => {
it('GET /:customerId --> should return success 200 after get points', async () => {
// test code
});
});
});
How can I solve this issue?
I'm assume that your docker container is running, but not as rootless. Make sure you are running your docker as rootless. You can try following:
$ sudo groupadd docker
$ sudo gpasswd -a $USER docker
Now make sure the following environment variables are set (or add them to ~/.bashrc)
export PATH=/home/ubuntu/bin:$PATH
export DOCKER_HOST=unix:///run/user/1001/docker.sock
Now try to restart docker
$ sudo service docker restart
After all steps try following docker command in terminal without sudo:
$ docker ps
If you are able to see your docker container, then it will solve your problem.

Running Karate UI tests with “driverTarget” in GitLab CI

Question was:
I would like to run Karate UI tests using the driverTarget options to test my Java Play app which is running locally during the same job with sbt run.
I have a simple assertion to check for a property but whenever the tests runs I keep getting "description":"TypeError: Cannot read property 'getAttribute' of null This is my karate-config.js:
if (env === 'ci') {
karate.log('using environment:', env);
karate.configure('driverTarget',
{
docker: 'justinribeiro/chrome-headless',
showDriverLog: true
});
}
This is my test scenario:
Scenario: test 1: some test
Given driver 'http://localhost:9000'
waitUntil("document.readyState == 'complete'")
match attribute('some selector', 'some attribute') == 'something'
My guess is that because justinribeiro/chrome-headless is running in its own container, localhost:9000 is different in the container compared to what's running outside of it.
Is there any workaround for this? thanks
A docker container cannot talk to localhost port as per what was posted: "My guess is that because justinribeiro/chrome-headless is running in its own container, localhost:9000 is different in the container compared to what's running outside of it."
To get around this and have docker container communicate with running app on localhost port use command host.docker.internal
Change to make:
From: Given driver 'http://localhost:9000'.
To: Given driver 'http://host.docker.internal:9000'
Additionally, I was able to use the ptrthomas/karate-chrome image in CI (GITLAB) by inserting the following inside my gitlab-ci.yml file
stages:
- uiTest
featureOne:
stage: uiTest
image: docker:latest
cache:
paths:
- .m2/repository/
services:
- docker:dind
script:
- docker run --name karate --rm --cap-add=SYS_ADMIN -v "$PWD":/karate -v
"$HOME"/.m2:/root/.m2 ptrthomas/karate-chrome &
- sleep 45
- docker exec -w /karate karate mvn test -DargLine='-Dkarate.env=docker' Dtest=testParallel
allow_failure: true
artifacts:
paths:
- reports
- ${CLOUD_APP_NAME}.log
my karate-config.js file looks like
if (karate.env == 'docker') {
karate.configure('driver', {
type: 'chrome',
showDriverLog: true,
start: false,
beforeStart: 'supervisorctl start ffmpeg',
afterStop: 'supervisorctl stop ffmpeg',
videoFile: '/tmp/karate.mp4'
});
}

How to run TestCafe runner class with Docker

I am new to TestCafe and want to run my testcases with runner class in Docker container.
I am able to run single testcase through Docker. But when i want to run with runner class, i am not able to do that.
I have followed this thread https://github.com/DevExpress/testcafe/issues/2761 but i don't know how to define "Environment initialization steps from the TestCafe Docker script in your runner."
my runner file
const testCafe = require('testcafe');
const fs = require('fs');
function runTest(tcOptions) {
testCafe('localhost', 8080, 8081)
.then(function(tc) {
let runner = tc.createRunner();
return runner
.src(['./apps/tests/*.test.js'])
.browsers(['firefox'])
.concurrency(4)
.reporter([
'list',
{
name: 'html',
output: './dist/testcafe/testCafe-report.html'
}
])
.screenshots('./dist/testcafe/testcafe-screenshots', true)
.run(tcOptions)
.catch(function(error) {
console.log(error);
});
})
.then(failedCount => {
if (failedCount > 0) console.log('Error Tests failed: ' + failedCount);
else console.log('All Desktop Tests Passed');
process.exit(0);
})
}
const tcOptions = {
debugMode: false
};
runTest(tcOptions);
and running this Docker command
docker run -v `pwd`/:/tests -e "NODE_PATH=/tests/node_modules" -it --entrypoint node testcafe/testcafe /tests/apps/testcafe//testcafe-desktop-run.js
{ Error: No tests to run. Either the test files contain no tests or the filter function is too restrictive.
at Bootstrapper._getTests (/tests/node_modules/testcafe/src/runner/bootstrapper.js:92:19) code: 'E1009', data: [] }
You need to define the full path to your test files or change your working directory to the /tests directory in the container.
Besides, this step is intended to run the in-memory display server. You may skip it if you are going to run tests in a headless browser.
Here is a command that works on my side with the Runner class:
docker run -v //c/Users/User/test-docker:/tests -w=/tests -it --entrypoint node testcafe/testcafe /tests/test-run.js

How do I set up postgres database in Jenkins pipeline?

I am using docker to simulate postgres database for my app. I was testing it in Cypress for some time and it works fine. I want to set up Jenkins for further testing, but I seem stuck.
On my device, I would use commands
docker create -e POSTGRES_DB=myDB -p 127.0.0.1:5432:5432 --name myDB postgres
docker start myDB
to create it. How can I simulate this in Jenkins pipeline? I need the DB for the app to work.
I use Dockerfile as my agent, and I have tried putting the ENV variables there, but it does not work. Docker is not installed on the pipeline.
The way I see it is either:
Create an image by using a
Somehow install docker inside the pipeline and use the same commands
Maybe with master/slave nodes? I don't understand them well yet.
This might be a use case for sidecar pattern one of Jenkins Pipeline's advanced features.
For example (from the above site):
node {
checkout scm
docker.image('mysql:5').withRun('-e "MYSQL_ROOT_PASSWORD=my-secret-pw"') { c ->
docker.image('mysql:5').inside("--link ${c.id}:db") {
/* Wait until mysql service is up */
sh 'while ! mysqladmin ping -hdb --silent; do sleep 1; done'
}
docker.image('centos:7').inside("--link ${c.id}:db") {
/*
* Run some tests which require MySQL, and assume that it is
* available on the host name `db`
*/
sh 'make check'
}
}
}
The above example uses the object exposed by withRun, which has the
running container’s ID available via the id property. Using the
container’s ID, the Pipeline can create a link by passing custom
Docker arguments to the inside() method.
Best thing is that the containers should be automatically stopped and removed when the work is done.
EDIT:
To use docker network instead you can do the following (open Jira to support this OOTB). Following helper function
def withDockerNetwork(Closure inner) {
try {
networkId = UUID.randomUUID().toString()
sh "docker network create ${networkId}"
inner.call(networkId)
} finally {
sh "docker network rm ${networkId}"
}
}
Actual usage
withDockerNetwork{ n ->
docker.image('sidecar').withRun("--network ${n} --name sidecar") { c->
docker.image('main').inside("--network ${n}") {
// do something with host "sidecar"
}
}
}
For declarative pipelines:
pipeline {
agent any
environment {
POSTGRES_HOST = 'localhost'
POSTGRES_USER = myuser'
}
stages {
stage('run!') {
steps {
script {
docker.image('postgres:9.6').withRun(
"-h ${env.POSTGRES_HOST} -e POSTGRES_USER=${env.POSTGRES_USER}"
) { db ->
// You can your image here but you need psql to be installed inside
docker.image('postgres:9.6').inside("--link ${db.id}:db") {
sh '''
psql --version
until psql -h ${POSTGRES_HOST} -U ${POSTGRES_USER} -c "select 1" > /dev/null 2>&1 || [ $RETRIES -eq 0 ]; do
echo "Waiting for postgres server, $((RETRIES-=1)) remaining attempts..."
sleep 1
done
'''
sh 'echo "your commands here"'
}
}
}
}
}
}
}
Related to Docker wait for postgresql to be running

docker dusk browser can't another web server container

set .env like the followings about Server address.
APP_URL=http://localhost:8000
APP_DOMAIN=localhost
I am using apache2 (docker container) as web server.
under this condition, to test with dusk, started up selenium/standalone-chrome as another container.
docker run -p 4444:4444 --name selenium --link apache2:apache2 -d selenium/standalone-chrome
to confirm the connection between docker containers,
used the following commands
docker exec -it selenium bash,
cat /etc/hosts/
result was
172.17.0.6 apache2 a1c15575e4c8
also confirmed ping apache2 from selenium container.
but from here, couldn't do dusk test using following command.
when I check the browser response, there was no contents.
docker exec apache2 php artisan dusk
I think setting is wrong. but can't notice it.
could you help?
the following is php source code.
DuskTestCase.php
abstract class DuskTestCase extends BaseTestCase
{
use CreatesApplication;
/**
* Prepare for Dusk test execution.
*
* #beforeClass
* #return void
*/
public static function prepare()
{
static::startChromeDriver();
}
/**
* Create the RemoteWebDriver instance.
*
* #return \Facebook\WebDriver\Remote\RemoteWebDriver
*/
protected function driver()
{
$options = (new ChromeOptions)->addArguments([
'--disable-gpu',
'--headless'
]);
return RemoteWebDriver::create(
'http://selenium:4444/wd/hub', DesiredCapabilities::chrome()->setCapability(
ChromeOptions::CAPABILITY, $options
)
);
}
}
ExampleTest.php
class ExampleTest extends DuskTestCase
{
public function testBasicExample()
{
$this->browse(function (Browser $browser) {
print_r($browser->visit('/')->resolver->elements);exit;
$browser->visit('/')
->assertSee('login');
});
}
}

Resources