Is there a way I can disable the prefetching of the sauce connect binary when I run an npm install on a polymer project?
I am running my tests on a CI that has no connection to the outside world.
I do not wish to use the sauce connect binary so I would like to be able to disable the fetching of the binary.
wct.conf.js:
const seleniumGridAddress = 'http://selenium-hub:4444/wd/hub';
const os = require('os');
let json;
if (os.platform() !== 'darwin') {
json = {
activeBrowsers: [{
browserName: 'chrome',
url: seleniumGridAddress
}
],
expanded: true,
suites: [
'test/**/*_test.html'
],
webserver: {
hostname: os.hostname()
},
}
} else {
json = {
expanded: true,
plugins: {
local: {
browsers: ["chrome"]
},
},
suites: [
'test/**/*_test.html'
]
}
}
module.exports = json;
Found out in the wct source code that you can set SKIP_WCT_SAUCE_POSTINSTALL_DOWNLOADas an environment variable to disable the fetching of the Sauce Connect binary cfr 2.0.0-pre.1 at https://github.com/Polymer/wct-sauce/blob/master/CHANGELOG.md
Related
I am trying to use Wallaby in conjunction with the dotenv-flow package. I currently have my wallaby.js config file setup like below:
require("dotenv-flow").config()
module.exports = function (wallaby) {
return {
files: [
'api/*',
'controllers/*',
'config/*',
'firebase/*',
'helpers/*',
'models/*',
'services/*',
'smtp/*',
'sockets/*'
],
tests: [
"test/**/*.test.mjs"
],
testFramework: "mocha",
env: {
type: "node",
params: {
env: "NODE_ENV=test"
}
}
};
};
I've tried a few other ways of writing the file including in esm module format. However, my tests run and my sequelize code complains that it wasn't passed environment variables to use for connecting to the development DB.
You are loading your .env file but then never using it's contents. Another problem is that wallaby doesn't understand the dotenv output so you have to massage it a little bit.
const environment = Object.entries(
require("dotenv-flow").config()['parsed']).
map( x => `${x[0]}=${x[1]}`).join(';'),
Then change your environment to something like this
env: {
runner: 'node',
params: {
env: environment
}
}
I'm new with Appium and WebdriverIO, I have an app created (a .zip file) and I want to test it with those 2 frameworks.
TL:DR - just go to the fourth code block.
I followed some tutorials and created a project containing
config files
test files
and of course a package.json.
First things first, my package.json:
{
"name": "my-test",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"wdio": "wdio run ./config/wdio.conf.js",
"ios.app": "./node_modules/.bin/wdio ./config/wdio.ios.app.conf.js"
},
"devDependencies": {
"#wdio/appium-service": "^7.16.16",
"#wdio/cli": "^7.16.16",
"#wdio/devtools-service": "^7.16.16",
"#wdio/local-runner": "^7.16.16",
"#wdio/mocha-framework": "^7.16.15",
"#wdio/spec-reporter": "^7.16.14",
"chai": "^4.3.6",
"chromedriver": "^99.0.0",
"wdio-chromedriver-service": "^7.2.8",
"webdriverio": "^7.16.16"
}
}
Then, my config files, divided in shared and ios :
shared.conf.js
exports.config = {
// ====================
// Runner and framework
// Configuration
// ====================
runner: "local",
framework: "mocha",
mochaOpts: {
timeout: 30000,
},
sync: true,
logLevel: "info",
deprecationWarnings: true,
bail: 0,
baseUrl: "localhost",
// path for appium sessions
path: "/wd/hub",
waitforTimeout: 15000,
connectionRetryTimeout: 90000,
connectionRetryCount: 3,
reporters: ["spec"],
autoGrantPermissions: true,
autoAcceptAlerts: true,
nativeWebTap: true,
// ====================
// Appium Configuration
// ====================
services: [
[
"appium",
{
// For options see
// https://github.com/webdriverio/webdriverio/tree/master/packages/wdio-appium-service
args: {
// Auto download ChromeDriver
relaxedSecurity: true,
// chromedriverAutodownload: true,
// For more arguments see
// https://github.com/webdriverio/webdriverio/tree/master/packages/wdio-appium-service
},
command: "appium",
},
],
],
port: 4723,
};
wdio.ios.app.conf.js
const { join } = require("path");
const { config } = require("./shared.conf");
// ============
// Specs
// ============
config.specs = ["./tests/specs/**/*.spec.js"];
// ============
// Capabilities
// ============
// For all capabilities please check
// http://appium.io/docs/en/writing-running-appium/caps/#general-capabilities
config.capabilities = [
{
// The defaults you need to have in your config
platformName: "iOS",
maxInstances: 1,
// For W3C the appium capabilities need to have an extension prefix
// This is `appium:` for all Appium Capabilities which can be found here
// http://appium.io/docs/en/writing-running-appium/caps/
"appium:deviceName": "iPhone 7",
"appium:platformVersion": "15.2",
"appium:orientation": "PORTRAIT",
// `automationName` will be mandatory, see
// https://github.com/appium/appium/releases/tag/v1.13.0
"appium:automationName": "XCUITest",
// The path to the app
"appium:app": join(process.cwd(), "../../../my-test.zip"),
// Read the reset strategies very well, they differ per platform, see
// http://appium.io/docs/en/writing-running-appium/other/reset-strategies/
"appium:noReset": true,
// How long (in seconds) Appium will wait for a new command from the client before assuming the client quit and ending the session
// default: 240
"appium:newCommandTimeout": 240,
},
];
exports.config = config;
So I created a very simple test file: there's a login screen, it finds the login textarea, writes the login, same for password, and push the button "signin":
describe("a test group", function () {
it("a test", async function () {
console.log("*******start*******");
// commands here
const selectUsername = 'type == "XCUIElementTypeTextField"';
const selectPassword = 'type == "XCUIElementTypeSecureTextField"';
const username = await $(`-ios predicate string:${selectUsername}`);
const password = await $(`-ios predicate string:${selectPassword}`);
const btnText = 'label == "SIGNIN"';
const loginBtn = await $(`-ios predicate string:${btnText}`);
await username.click();
await username.addValue("my#email.com");
await password.click();
await password.addValue("mypassword");
await loginBtn.click();
});
});
My issue here is that when the test is running
a) if I open the appium inspector, I can't find any running session, even if it has to exist somewhere:
plus (minor) I think the session never stops. If I re-run the test, the app running in the simulator shows the page of already logged-in, failing the test (because does not find the login/password fields).
Where are the sessions? and what I'm doing wrong?
Solved.
I was not able to edit the path in config file, but if I change the remote path in appium inspector to / , it finds the current session.
I'm trying to mock the react-native-image-crop-picker package (the openCamera function specifically) in Detox but I'm not managing to do it. Detox simply does not consider the mock.
.detoxrc.json:
{
"testRunner": "jest",
"runnerConfig": "e2e/config.json",
"uiHierarchy": "enabled",
"configurations": {
"android.emu.debug": {
"binaryPath": "android/app/build/outputs/apk/debug/app-debug.apk",
"build": "yarn detox:prepare",
"type": "android.emulator",
"device": {
"avdName": "Pixel_4_API_29"
}
}
}
}
.config.json:
{
"preset": "ts-jest",
"testEnvironment": "./environment",
"testRunner": "jest-circus/runner",
"testTimeout": 120000,
"reporters": ["detox/runners/jest/streamlineReporter"],
"verbose": true,
"testMatch": [
"**/__tests__/**/*.js?(x)",
"**/?(*.)(e2e).js?(x)",
"**/__tests__/**/*.ts?(x)",
"**/?(*.)(e2e).ts?(x)"
]
}
config.js:
require('#babel/register')({
//cache: true,
presets: [require('metro-react-native-babel-preset')],
plugins: [require('#babel/plugin-transform-runtime').default],
only: ['./e2e', './ts', './js'],
ignore: ['node_modules'],
});
environment.js:
const {
DetoxCircusEnvironment,
SpecReporter,
WorkerAssignReporter,
} = require('detox/runners/jest-circus');
class CustomDetoxEnvironment extends DetoxCircusEnvironment {
constructor(config) {
super(config);
// Can be safely removed, if you are content with the default value (=300000ms)
this.initTimeout = 300000;
// This takes care of generating status logs on a per-spec basis. By default, Jest only reports at file-level.
// This is strictly optional.
this.registerListeners({
SpecReporter,
WorkerAssignReporter,
});
}
}
module.exports = CustomDetoxEnvironment;
metro.config.js:
const blacklist = require('metro-config/src/defaults/blacklist');
const defaultSourceExts = require('metro-config/src/defaults/defaults')
.sourceExts;
/**
* Metro configuration for React Native
* https://github.com/facebook/react-native
*
* #format
*/
module.exports = {
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: false,
},
}),
},
/**
*
* Blacklist is a function that takes an array of regexes
* and combines them with the default blacklist to return a single regex.
*
*/
resolver: {
blacklistRE: blacklist([/.\/amplify\/.*/]),
sourceExts: process.env.RN_SRC_EXT
? process.env.RN_SRC_EXT.split(',').concat(defaultSourceExts)
: defaultSourceExts,
},
};
E2E folder:
E2E Folder
ImageCropPicker.e2e.js:
import ImageCropPicker from 'react-native-image-crop-picker';
ImageCropPicker.openCamera = function openCamera() {
console.tron.log('mocked');
return {
mime: 'test',
data: 'test',
};
};
I also tried to put the ImageCropPicker.e2e.js file outside the mocks folder, but it did not work as well.
Detox, Node, Device and OS versions:
Detox: 17.6.0
Node: 10.23.0
Device: Pixel 4 API 29
OS: Linux Pop!_OS 20.10
React-Native: 0.62.0
Can you help me?
I appreciate your time!
I'm currently running a node application with Pm2, but am struggling to get logs.
Currently, if I start the script with just node index.js my logger function (using winston) sends the logs to the screen just fine. The first two lines in the below video ("IS THIS SHOWING UP" and "YA") are from console.log statements inside my javascript files, and the latter lines are from my logger function. It looks like this:
However, in the deployment of my server, I'm using an ecosystem.config.js file with Pm2. When I run my server with pm2 start index.js, the logger also works. HOWEVER, when I start my server using my ecosystem file, the pm2 instance only sends the console.log statements to the output, not the logs output by the winston logger.
This means that I've got something misconfigured in my ecosystem.config.js file. What's going wrong?
package.json (script that kicks off the pm2 instance)
{
"name": "graphqlCourse",
...
"scripts": {
"prod:serve": "NODE_ENV=production pm2 startOrRestart ecosystem.config.js"
},
"dependencies": {
...
ecosystem.config.js
module.exports = {
apps: [
/// I believe that something is misconfigured in here relating to logging.....
{
name: process.env.APP_NAME,
args: ["--color"],
interpreter: process.env.NODE_PATH,
cwd: path.resolve(process.env.PROJECT_PATH, 'current' ),
script: 'dist/index.js',
instances: process.env.INSTANCES || 0,
exec_mode: "cluster",
env: {
...process.env,
},
},
],
deploy: {
production: {
user: "harrison",
host: process.env.HOST,
key: "~/.ssh/id_rsa2",
ref: "origin/master",
repo: process.env.GIT_REPO,
path: process.env.PROJECT_PATH,
"pre-deploy-local": `scp -Cr envs harrison#${process.env.HOST}:${process.env.PROJECT_PATH}/current`,
"post-deploy": `yarn install --ignore-engines && \
pwd && \
yarn prod:build && \
yarn prod:serve`,
},
},
};
-- EDIT --
Here's my logger as well:
import winston, { format } from "winston";
import "winston-daily-rotate-file"; // Attaches new transport to winston.transports
// Define the custom settings for each transport (file, console)
let consoleOptions = {
level: "info",
handleExceptions: true,
stderrLevels: ["error"],
silent: process.env.SILENT === "true",
format: format.combine(
format.colorize(),
format.align(),
format.printf((info) => {
const { level, message } = info;
return `[${level}]: ${message}`;
})
),
};
let consoleTransport = new winston.transports.Console(consoleOptions);
// Log rotation
const transport = new winston.transports.DailyRotateFile({
filename: `API_${process.env.NODE_ENV}.log`,
dirname: `./${
process.env.NODE_ENV === "production" ? "dist" : "server"
}/logs`,
frequency: null, // Rely on date pattern, rotate daily
datePattern: "YYYY-MM-DD",
zippedArchive: true,
maxSize: "10m",
maxFiles: "14d",
format: format.combine(format.timestamp(), format.json()),
});
transport.on("rotate", (oldFileName, newFilename) => {
console.log(`ROTATING LOGS. OLD: ${oldFileName} -- NEW: ${newFilename}`);
});
// Handles input from Morgan.
var writer = new winston.createLogger({
transports: [transport],
});
// Handles logger.XX calls from within app.
export const logger = new winston.createLogger({
transports: [consoleTransport, transport],
exitOnError: false, // do not exit on handled exceptions
});
// Recieves message from morganToWinston
logger.stream = {
write: function (message) {
writer.info(message);
},
};
My goal is to let a webpack project be setup through node command crateEntireWepbackProject.js file.
I want to execute commands on the shell from a js file, so I can let them run automatically and later on also include custom specifications for a project.
The js file is not from within webpack, but has the commands to create a wepback project from scratch and makes the installs etc. just by me typing node createEntireWebpackProject.js
You do not need to write it from scratch. The best practice is using yeoman. There are a lot of generators with webpack. For example:
const Generator = require('yeoman-generator');
const mkdirp = require('mkdirp');
const path = require('path');
module.exports = class extends Generator {
prompting() {
this.log('Welcome to the classy example generator!');
const prompts = [
{
type: 'input',
name: 'name',
message: 'Name?',
default: this.appname,
}];
return this.prompt(prompts).then((props) => {
this.props = props;
});
}
default() {
if (path.basename(this.destinationPath()) !== this.props.name) {
this.log(
`Your application must be inside a folder named ${this.props.name}`);
this.log('I\'ll automatically create this folder.');
mkdirp(this.props.name);
this.destinationRoot(this.destinationPath(this.props.name));
}
}
writing() {
this.createPackageJson();
this.copyFiles();
this.fillTemplates();
this.makeCommands();
}
install() {
this.npmInstall(['bunyan', 'dotenv-safe'], { save: true });
this.npmInstall(['eslint', 'eslint-config-airbnb-base', 'eslint-plugin-import', 'jest'], { 'save-dev': true });
}
createPackageJson() {
this.fs.extendJSON('package.json', {
name: this.props.name,
version: '0.1.0',
main: 'src/app.js',
scripts: {
cs: 'eslint src/* __tests__/*',
'cs:fix': 'eslint src/* __tests__/* --fix',
start: 'node src/app.js',
test: 'npm run cs && jest',
},
dependencies: {},
devDependencies: {},
engines: {
node: '^8.1.0',
},
private: true,
jest: {
testEnvironment: 'node',
transform: {},
collectCoverage: true,
},
});
}
copyFiles() {
[
'.dockerignore',
'.eslintrc.json',
'src/app.js',
].forEach(name => this.fs.copy(this.templatePath(name), this.destinationPath(name)));
}
fillTemplates() {
this.fs.copyTpl(
this.templatePath('README.md'),
this.destinationPath('README.md'),
{
name: this.props.name,
});
}
makeCommands() {
this.spawnCommandSync('git' ['init']);
this.spawnCommandSync('git', ['add', '.']);
this.spawnCommandSync('git', ['commit', '-am', '"yo scaffolded app"']);
}
};