TestCafe docker- unable to run tests using runner class - docker

I have all my tests running in a docker container and it works fine. Since I have a few test files which need concurrent tests and a file which doesn't need a concurrent test that is the reason I need to create a test runner to run my tests. Here is what my test runner class looks like:
const createTestCafe = require('testcafe');
let testcafe = null;
createTestCafe('localhost', 1337, 1338)
.then((tc) => {
testcafe = tc;
const runner1 = testcafe.createRunner();
const runner2 = testcafe.createRunner();
const promise1 = runner1
.src(['/tests/uitests/**/conctests/accounttest.js', '/tests/uitests/**/conctests/dashtest.js'])
.browsers('chromium')
.screenshots({ takeOnFails: true })
.reporter(['spec', {
name: 'html',
output: 'resultsrunner1.html' }, {
name: 'xunit',
output: 'res1.xml',
}])
.concurrency(3)
.run({
skipJsErrors: true,
quarantineMode: true,
});
const promise2 = runner2
.src('/tests/uitests/**/conctests/roletest.js')
.browsers('chromium')
.screenshots({ takeOnFails: true })
.reporter(['spec', {
name: 'html',
output: 'resultsrunner2.html' }, {
name: 'xunit',
output: 'res2.xml',
}])
.run({
skipJsErrors: true,
quarantineMode: true,
});
return Promise.all([promise1, promise2]);
})
.then(() => {
testcafe.close();
process.exit();
})
.catch((err) => {
console.log(err);
testcafe.close();
process.exit(1);
});
when I run it using the command:
docker run --net=host -v `pwd`:/tests -it --entrypoint node testcafe /tests/testrunner.js
I get this error:
Error: Unable to establish one or more of the specified browser connections. This can be caused by network issues or remote device failure.
at /tests/node_modules/testcafe/src/runner/browser-set.js:84:30
at Generator.next (<anonymous>)
at step (/tests/node_modules/babel-runtime/helpers/asyncToGenerator.js:17:30)
at /tests/node_modules/babel-runtime/helpers/asyncToGenerator.js:35:14
at new Promise (<anonymous>)
at new F (/tests/node_modules/core-js/library/modules/_export.js:36:28)
at /tests/node_modules/babel-runtime/helpers/asyncToGenerator.js:14:12
at BrowserSet._waitConnectionsOpened (/tests/node_modules/testcafe/src/runner/browser-set.js:77:37)
at _waitConnectionsOpened (/tests/node_modules/testcafe/src/runner/browser-set.js:107:35)
at invokeCallback (/tests/node_modules/pinkie/index.js:60:12)
at Array.forEach (<anonymous>)
at publish (/tests/node_modules/pinkie/index.js:147:32)
at Array.publishFulfillment (/tests/node_modules/pinkie/index.js:152:2)
at Immediate.asyncFlush (/tests/node_modules/pinkie/index.js:17:19)
at runCallback (timers.js:706:11)
at tryOnImmediate (timers.js:676:5)
at processImmediate (timers.js:658:5)
at process.topLevelDomainCallback (domain.js:126:23)
I tried firefox and chromium --no-sandbox as well but nothing worked for me. In my case, I'm using the existing available browser image from the TestCafe. Please suggest as all my tests are stuck right now.

Try to use a headless browser. If you need to run tests with the browser UI, perform this step in your runner to initialize the in-memory display server.

Related

AWS CodeBuild With the CDK "Error: .git/HEAD does not exist"

My desire is to build the CDK Cloud Formation stacks using AWS Code Pipeline, from the CDK library aws-cdk-lib/pipelines. When running cdk ls in the CLI, everything works as expected. I can successfully deploy the pipeline as well with cdk deploy.
Error Message:
[Container] 2022/12/30 09:18:36 Running command npx cdk synth
Error: .git/HEAD does not exist
at gitHeadPath (/codebuild/output/src224694107/src/backend/node_modules/git-branch/index.js:36:11)
at branch (/codebuild/output/src224694107/src/backend/node_modules/git-branch/index.js:14:28)
at /codebuild/output/src224694107/src/backend/src/context/getContext.ts:11:41
at new Promise (<anonymous>)
at Object.exports.getContext (/codebuild/output/src224694107/src/backend/src/context/getContext.ts:9:12)
at createStack (/codebuild/output/src224694107/src/backend/bin/template.ts:9:25)
at Object.<anonymous> (/codebuild/output/src224694107/src/backend/bin/template.ts:18:1)
at Module._compile (internal/modules/cjs/loader.js:1085:14)
at Module.m._compile (/codebuild/output/src224694107/src/backend/node_modules/ts-node/src/index.ts:1618:23)
at Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
(node:179) UnhandledPromiseRejectionWarning: undefined
(Use `node --trace-warnings ...` to show where the warning was created)
(node:179) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:179) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
CDK Pipeline Code:
this.codePipeline = new CodePipeline(this, `${environment}-pipeline-${appName}`, {
pipelineName: `${environment}-pipeline-${appName}`,
selfMutation: true,
crossAccountKeys: false,
role: this.codePipelineRole,
synth: new ShellStep("Deployment", {
input: CodePipelineSource.codeCommit(this.codeRepository, environment),
installCommands: ["npm uninstall -g aws-cdk", "npm i -g npm#latest", "npm install -g aws-cdk"],
commands: ["cd backend", "npm ci", "npm run build", "npx cdk synth"],
primaryOutputDirectory: "backend/cdk.out",
}),
});
getContext Function:
export const getContext = (app: App): Promise<CDKContext> => {
return new Promise(async (resolve, reject) => {
try {
const currentBranch = await gitBranch();
const environment = app.node.tryGetContext("environments").find((e: any) => e.branchName === currentBranch);
const globals = app.node.tryGetContext("globals");
return resolve({...globals, ...environment});
}
catch (error) {
console.error("error", error);
return reject();
}
})
}
Package.json dependencies:
"dependencies": {
"#aws-cdk/aws-appsync-alpha": "^2.55.1-alpha.0",
"aws-cdk-lib": "^2.58.0",
"aws-sdk": "^2.1278.0",
"constructs": "^10.1.204",
"git-branch": "^2.0.1",
"source-map-support": "^0.5.21"
}
Code Build has two options for cloning repositories:
CodePipeline Default - "AWS CodePipeline uses the default zip format for artifacts in the pipeline. Does not include git metadata about the repository"
Full Clone - "AWS CodePipeline passes metadata about the repository that allows subsequent actions to do a full git clone. Only supported for AWS CodeBuild actions."
Quotes taken from the console.
Therefore, the pipeline definition needed to add a Code Commit source prop to tell the CDK to do a full clone. CDK Docs for options here.
Updating the input:
input: CodePipelineSource.codeCommit(this.codeRepository, environment, {
codeBuildCloneOutput: true
})
codeBuildCloneOutput - "If this is set, the next CodeBuild job clones the repository (instead of CodePipeline downloading the files)." This allows for a full clone of the repository, and will remove the error.
CDK Permissions Update:
This image shows now the CodeBuild can do a GitPull:

Testcafe docker run shows error on specifying global request hook in .testcaferc.js file

I get an error The hook (object) is not of expected type (RequestHook subclass).
I notice this error when I run the test using the testcafe docker image.
I use the command:
docker run -v //c/testproject:/mytests -it testcafe/testcafe "chromium:headless:emulation:device=iPhone X" /mytests/testone.js --config-file /mytests/.testcaferc.js
I have the following code in my .testcaferc.js file
const { RequestMock} = require("testcafe");
const mock = RequestMock()
.onRequestTo('https://a360cdn.azureedge.net/javascript/a360.consent.default.js')
.respond(null, 200)
module.exports = {
hooks: {
request: [mock]
},
browsers: "chromium:headless:emulation:device=iPhone X",
skipJsErrors: true,
skipUncaughtErrors: true,
};
My test file has the following code:
import {Selector} from 'testcafe'
fixture `fixture 1`
test.page(`https://www.chileautos.cl/`)(`First test`, async t => {
await t.expect(Selector(`div.element-id`).exists).ok()
});
And my package.json is as below:
{
"scripts": {
"b": "testcafe ./testone.js"
},
"dependencies": {
"testcafe": "^2.0.1"
}
}
Note: When i run my test without testcafe docker image, the mock request works fine.
For example, I can see the test running good when I run the test using npm run b
But if I run the test using the following command:
docker run -v //c/testproject:/mytests -it testcafe/testcafe "chromium:headless:emulation:device=iPhone X" /mytests/testone.js --config-file /mytests/.testcaferc.js
I see the following error:
ERROR Cannot prepare tests due to the following error:
The hook (object) is not of expected type (RequestHook subclass).
Type "testcafe -h" for help.
You can use a mounted folder as a path only for tests. You need to move the configuration file to the root folder or create a custom Docker image that extends the basic TestCafe Docker image and allows specifying configuration file.

Jest did not exit one second after the test run has completed (with Nuxt and Jest)

For unknown reasons my Jest tests seem to block at the end of my CI via Travis.
The Travis logs say as follow:
Test Suites: 5 passed, 5 total
Tests: 31 passed, 31 total
Snapshots: 0 total
Time: 21.993s
Jest did not exit one second after the test run has completed.
This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with --detectOpenHandles to troubleshoot this issue.
Note that --detectOpenHandles does not display anything.
As you can see my tests pass but do not exit, even though I do the following :
describe('[INTEGRATION] Index.test.js', () => {
beforeAll(async () => {
const rootDir = resolve(__dirname, '../..');
let config = {};
// ... config
nuxt = new Nuxt(config);
new Builder(nuxt).build();
await nuxt.listen(3000, 'localhost');
homePage = await nuxt.renderAndGetWindow('http://localhost:3000/');
}, 30000);
// This is called after every suite (even during the CI process)
afterAll(() => {
nuxt.close();
});
// ... my tests
});
My tests work fine locally but only do this during the CI process via Travis.
Here is the content of my Jest config file:
module.exports = {
verbose: true,
moduleFileExtensions: ['js', 'vue', 'json'],
transform: {
'^.+\\.js$': 'babel-jest',
'.*\\.(vue)$': 'jest-vue-preprocessor',
},
setupTestFrameworkScriptFile: './jest.setup.js',
silent: true,
};
With jest.setup.js containing jest.setTimeout(30000);.
Finally, here is my .travis.yml config file:
language: 'node_js'
node_js: '8'
cache:
directories:
- 'node_modules'
before_script:
- npm run build
- npm run lint
- npm install
- npm run generate
What could be causing this problem? The timeout shouldn't be it as it is needed in order to execute all my integration tests, and I close my nuxtsession after my integration test suites.
Nothing has majorly been changed between yesterday when it worked and today.
I think you may need to make sure you wait for the nuxt.close() call to resolve. It looks like close is asynchronous and emits a promise that resolves when the connection is actually closed. So Jest probably finishes up before that asynchronous operation finishes. And it's really a timing issue so the CI machine may run things slightly differently causing the close call to take longer than it does on your local machine.
Try changing your afterAll to something like this:
afterAll(async () => {
await nuxt.close();
});

How to get started with dockerode

I am planning on running my app in docker. I want to dynamically start, stop, build, run commands, ... on docker container. I found a tool named dockerode. Here is the project repos. This project has doc, but I am not understanding very well. I would like to understand few thing. This is how to build an image
docker.createContainer({Image: 'ubuntu', Cmd: ['/bin/bash'], name: 'ubuntu-test'}, function (err, container) {
container.start(function (err, data) {
//...
});
});
It is possible to make RUN apt-get update like when we use Dockerfile, or RUN ADD /path/host /path/docker during build ? how to move my app into container after build ?
Let's see this code :
//tty:true
docker.createContainer({ /*...*/ Tty: true /*...*/ }, function(err, container) {
/* ... */
container.attach({stream: true, stdout: true, stderr: true}, function (err, stream) {
stream.pipe(process.stdout);
});
/* ... */
}
How can I know how many params I can put here { /*...*/ Tty: true /*...*/ } ?
Has someone tried this package too ? please help me to start with.
Dockerode is just a node wrapper for Docker API. You can find all params you can use for each command in api docs.
For example docker.createContainer will call POST /containers/create (docs are here: https://docs.docker.com/engine/reference/api/docker_remote_api_v1.24/#/create-a-container)
Check files in lib folder of dockerode repo to see what api command is wrapped for each dockerode method.

how to catch the exit event of process in docker

I create a process with nodejs on docker container, but I don't catch the exit event of the process, the docker version is 1.0.1, but the same code is okay on the version 0.91 of docker.
var spawn = require('child_process').spawn;
var exec = spawn('docker', 'run busybox /etc/bin/bash each hello world');
exec.on('error', function(err){
console.log(err);
});
exec.stdout.on('data', function(data) {
console.log('stdout: ' + data);
});
exec.on('exit', function(err){
console.log('exit')
});
I think the problem is in the use of spawn. The second parameter should be an array according to the nodejs docs.
In a quick test, your code launches docker without any arguments, at least on node v0.10.28.

Resources