Create React App not reusing existing tab - javascript

I have been developing a web app (for a few months) that is built on top of CRA. Everything has been working as intended until this morning when I realized that the npm (or yarn) start script is no longer reusing the existing tab I have open in Chrome. It instead opens a new tab at localhost:3000 even if there are existing tabs at localhost:3000. I have been investigating this for a few hours but am yet to find a solution. I added a log statement in the CRA script (within my node modules) that handles the reusing of existing tabs upon startup of the app.
function startBrowserProcess(browser, url) {
// If we're on OS X, the user hasn't specifically
// requested a different browser, we can try opening
// Chrome with AppleScript. This lets us reuse an
// existing tab when possible instead of creating a new one.
const shouldTryOpenChromeWithAppleScript =
process.platform === 'darwin' &&
(typeof browser !== 'string' || browser === OSX_CHROME);
if (shouldTryOpenChromeWithAppleScript) {
try {
// Try our best to reuse existing tab
// on OS X Google Chrome with AppleScript
execSync('ps cax | grep "Google Chrome"');
execSync('osascript openChrome.applescript "' + encodeURI(url) + '"', {
cwd: __dirname,
stdio: 'ignore',
});
return true;
} catch (err) {
console.log(err);
// Ignore errors.
}
}
This is the output of the log statement:
{ Error: Command failed: osascript openChrome.applescript "http://localhost:3000/"
at checkExecSyncError (child_process.js:621:11)
at execSync (child_process.js:658:13)
at startBrowserProcess (/Users/***/Desktop/WorkSpace/React/***/node_modules/react-dev-utils/openBrowser.js:78:7)
at openBrowser (/Users/***/Desktop/WorkSpace/React/***/node_modules/react-dev-utils/openBrowser.js:122:14)
at Server.devServer.listen.err (/Users/***/Desktop/WorkSpace/React/***/node_modules/react-scripts/scripts/start.js:100:7)
at Server.returnValue.listeningApp.listen (/Users/***/Desktop/WorkSpace/React/***/node_modules/webpack-dev-server/lib/Server.js:604:10)
at Object.onceWrapper (events.js:273:13)
at Server.emit (events.js:182:13)
at emitListeningNT (net.js:1328:10)
at process.internalTickCallback (internal/process/next_tick.js:72:19)
status: 1,
signal: null,
output: [ null, null, null ],
pid: 2691,
stdout: null,
stderr: null }
It seems to have an issue running the Applescript command that handles this but I am unsure why. One of the other developers that is working on the same app locally is not having this issue. One change I made recently was upgrading to the new macOS Mojave. But the other developer just upgraded as well and is not having this issue.
Does anyone know what could be wrong?

To avoid opening a new tab,
you'll need to create an .env file in the root of your project and add this line,
BROWSER=none.
As shown here

Turns out after I upgraded Mojave I denied interface access to Google Chrome from my terminal. So it was unable to run the "reuse" tab script.

Related

Unexpected stdout of "'Saved file tree to doc-filelist.js\n' + 'Copied JS to doc-script.js\n' + 'Compiled CSS to doc-style.css\n'

I am working on a Docker Swarm data visualization tool with a team.
It works as follows:
Our backend is set up in a way that terminal commands can be executed from our code, where these terminal commands have been promisified and the result of this command should be a string of nodeIDs corresponding to the active nodes in my Docker Swarm. This data is then passed to another helper function, however, I am unable to move past the previously explained step due to an unexpected output from my promisified terminal command.
const getNodeIDs = () => {
console.log('in nodeID helper function');
return execProm("docker node ls --format '{{json .ID}}'").then(
(rawNodeIDs) => {
console.log('rawNodeIds: ', rawNodeIDs);
const parsedNodeIDs = parseRawData(rawNodeIDs);
console.log('parsedNodeIDs: ', parsedNodeIDs);
return parsedNodeIDs;
}
);
};
My code fails on line 6 due to the fact that the data being passed to my parseRawData function is not what it is expected. The console log on line 5 above returns as follows:
{
stdout: 'Saved file tree to doc-filelist.js\n' +
'Copied JS to doc-script.js\n' +
'Compiled CSS to doc-style.css\n',
stderr: ''
}
In addition to this being the wrong output, every time I invoke this command, a new file is created in my codebase labeled "docs" with the following three files inside: doc-filelist.js, doc-script.js, doc-style.css. I am working in a team of 4 other engineers, and I seem to be the only person experiencing this behavior. When I attempt to run the terminal command (featured on line 3 in the first block of code) directly in the terminal itself, I receive the expected output of
"odwch32vsynhxbc0ia2nwicag"
which is the nodeID of the single node currently in my Docker Swarm and what I should be receiving when invoking the terminal command from the code.
I've only been able to find one other stack overflow article dealing with the same issue in which that person was told to try running the terminal command
npm uninstall -g docker
which I have done, and this did not fix my issues. I've also looked into making edits to the Docker daemon itself, but am unsure that this is the real root of the issue. Since I am the only person on my team that seems to be encountering this bug, I have reason to believe that this error has something to do with my dev environment. My containers are running on Docker v4.15.0 and I am working on macOS on an M1 chip computer.
Thanks!

Codeceptjs: I got ERROR webdriver: Request failed with status 404 due to unknown command when trying to click to an mobile element

When I tried to click an element using Appium and Codeceptjs, I got the error below:
ERROR webdriver: Request failed with status 404 due to unknown command: The requested resource could not be found, or a request was received using an HTTP method that is not supported by the mapped resource.
Full log below:
-- FAILURES:
1) login
test something:
The requested resource could not be found, or a request was received using an HTTP method that is not supported by the mapped resource
at getErrorFromResponseBody (C:\Users\DELL\node_modules\webdriver\build\utils.js:197:12)
at NodeJSRequest._request (C:\Users\DELL\node_modules\webdriver\build\request\index.js:158:60)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at async Browser.wrapCommandFn (C:\Users\DELL\node_modules\#wdio\utils\build\shim.js:137:29)
Scenario Steps:
- I.click("//android.widget.Button[#content-desc="Login"]/android.widget.TextView[2]") at Test.<anonymous> (.\login_test.js:9:7)
- I.seeAppIsInstalled("com.wdiodemoapp") at Test.<anonymous> (.\login_test.js:8:7)
This error log appears when the codeceptjs call I.click() api I think. I tried use Accesibility ID and Xpath to get element but get the same error
My test code:
Feature('login');
const LOGIN_ICON = '~Login'
const LOGIN_BTN = '~button-LOGIN'
const EMAIL_TXT_FIELD = '~input-email'
const PASSWORD_TXT_FIELD = '~input-password'
Scenario('test something', ({ I }) => {
I.seeAppIsInstalled("com.wdiodemoapp")
I.click('//android.widget.Button[#content-desc="Login"]/android.widget.TextView[2]')
I.fillField(EMAIL_TXT_FIELD, "abc")
I.fillField(PASSWORD_TXT_FIELD, "12345678")
I.click(LOGIN_BTN)
});
Below are my config file:
exports.config = {
tests: './*_test.js',
output: './output',
helpers: {
Appium: {
platform: 'Android',
device: 'emulator',
desiredCapabilities: {
appPackage: "com.wdiodemoapp",
appActivity: "MainActivity",
deviceName: "emulator-5554",
platformName: "Android",
automationName: "UiAutomator2",
}
}
},
include: {
I: './steps_file.js'
},
bootstrap: null,
mocha: {},
name: 'codecept-mobile-auto'
}
Any idea please !!! I am the new to codeceptjs testing tool
Thank a lot
I had two things I had to do to fix this issue:
I needed the platform to be set to 'android' instead of 'Android'. It looks like codecept does a case sensitive check on whether to run the Touch click or Element click. If I'm reading the code right, you can see it in this line from their WebDriver.js file.
const clickMethod = this.browser.isMobile && this.browser.capabilities.platformName !== 'android' ? 'touchClick' : 'elementClick';
If you look through the Appium calls, this changes the API from /touch/click to /element/:elementid/click which works correctly.
Not sure if this was necessary, but I did run an npm update / npm install to refresh all of my packages. This was after updating to the latest version of appium.
Hope this helps and someone else doesn't have to beat their head against this wall.

Passing custom Chrome profile directory when starting Cypress

We would like to use a custom Chrome profile directory for our Cypress tests. The application we are testing uses a Web SQL database which needs to be loaded into the Chrome browser. We already tried this command which should be a valid chromium argument.
launchOptions.args.push('--user-data-dir=/Users/testuser/dev/chrome')
Our setup:
MacOs
Chrome v93
Cypress v8.3.0
Cypress Cucumber Preprocessor v4.1.0
The code we tried in our index.js (plugins folder):
const browserify = require('#cypress/browserify-preprocessor');
const cucumber = require('cypress-cucumber-preprocessor').default;
const resolve = require('resolve');
module.exports = (on, config) => {
const options = {
...browserify.defaultOptions,
typescript: resolve.sync('typescript', { baseDir: config.projectRoot }),
};
on('file:preprocessor', cucumber(options));
on('before:browser:launch', (browser = {}, launchOptions) => {
// `args` is an array of all the arguments that will
// be passed to browsers when it launches
console.log(launchOptions.args) // print all current args
launchOptions.args.push('--user-data-dir=/Users/testuser/dev/chrome')
launchOptions.args.push('--auto-open-devtools-for-tabs')
return launchOptions
})
};
This seems not to be working while the --auto-open-devtools-for-tabs command is working fine, but the custom profile is not loaded. Is this a known issue? Or can we debug to see what is happening?
update 24/9/2021
I see that the argument is passed to Chrome by Cypress, but Cypress overrides the Chrome profile path. Steps to reproduce:
Add launchOptions argument with --user-data-dir like mentioned above
Open Cypress dashboard (npx cypress open)
Run 1 test in Chrome
Chrome browser opens, type chrome://version/ in URL bar
--user-data-dir=/Users/testuser/dev/chrome is listed in the Command Line panel, but I also see --user-data-dir=/Users/xxxxx/Library/Application Support/Cypress/cy/production/browsers/chrome-stable/interactive listed, and that is the Profile Path which is being used by Cypress
According to this thread I understand that this is how Cypress works https://github.com/cypress-io/cypress/issues/3671

How can I see what EXACTLY is Node.js passing as command line arguments?

Running commands via Node's execFile on windows is a nightmare. Many a time, when I get a "Command failed" error if I copy the "failed" command from the error it executes just fine. Sometimes, trying windowsVerbatimArguments: true helps but usually, it does not.
For example, right now I am running Visual Studio's MSBuild.exe, with the following parameters in Node.js - I have printed the exact array passed to execFile:
Running MSBuild with parameters: [
'D:\\PROJECT\\vcxproj\\HelperProject.vcxproj',
'-t:OutputBuildMacro',
'-p:ProjectToImport=D:\\PROJECT\\vcxproj\\HelperProject.vcxproj;PropertyToGet="OutputType,BlueProjectsVersionPropsGlobalIncluded"'
]
Executable path: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\amd64\MSBuild.exe
If I copy these items from the array and paste them into the command line it will run just fine. Clearly, Node.js is messing up when passing the command. Because this has happened to me many times, just a few weeks ago with Irfan View, I am not looking for a solution for this specific problem - I would just be asking a similar question again very soon.
I am looking for a guide how to see what is Node.js actually passing so that I can make a guess how to edit the parameters so that they are accepted by the command I call.
How to see what is Node.js exactly sunning why I call execFile?
You can use NODE_DEBUG environment variable to get extra info out of NodeJS.
You can find docs here.
For example this index.js:
const { execFile } = require('child_process');
execFile('/bin/ls', ['/Volumes'], {}, (err, stdout, stderr) => {
if (err) {
console.error('Command failed');
} else {
console.log('Command succeded');
}
});
And to enable debug logging for child_process module execute:
NODE_DEBUG=CHILD_PROCESS node index.js
(On Windows the environment variable seems to be set differently)
set NODE_DEBUG=CHILD_PROCESS & node index.js
in my case it produces this kind of output:
CHILD_PROCESS 85208: spawn {
cwd: null,
env: null,
gid: undefined,
uid: undefined,
shell: false,
windowsHide: false,
windowsVerbatimArguments: false,
args: [ '/bin/ls', '/Volumes' ],
detached: false,
envPairs: [
'COMMAND_MODE=unix2003',
...
'TERM=xterm-256color',
'NODE_DEBUG=CHILD_PROCESS',
],
file: '/bin/ls'
}
P.S.
Setting NODE_DEBUG=* will produce all debug log information that is available in NodeJS.

How to run all test scripts on a single browser instance

I am using Testcafe (free version) with Java Script. I want to run all my test cases (resides in multiple test scripts in __test__ directory) in a single browser instance (That way 1 time log in) per browser type.
For example, 1 instance for chrome and 1 instance for safari but all tests will run before closing the browser.
If a test fails, I want the screenshot is taken and count number of the test failures. But do want to continue.
I'm doing all on Node 12 Docker image, so it is best if I don't need to install anything else.
How do I do this with Testcafe?
const createTestCafe = require('testcafe')
let testcafe = null
let runner = null
createTestCafe('localhost', 1337, 1338)
.then(tc => {
testcafe = tc
const runner = testcafe.createRunner()
return runner
.src([ '__test__/*.js' ])
.browsers([ 'chrome:headless --no-sandbox --disable-gpu', 'safari' ])
.screenshots('./reports/screenshots/', true)
.run({
selectorTimeout: 10000,
assertionTimeout: 10000,
})
})
runner
.screenshots({
path: 'reports/screenshots/',
takeOnFails: true,
})
.then(failedCount => {
console.log('Tests failed: ' + failedCount)
testcafe.close()
})
.catch(error => {
console.log("An ERROR detected:" + error)
})
This is how you install chrome on Dockerfile. Can someone tell me how to install Firefox on Dockerfile?
RUN sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' && \
http_proxy=${http_proxy} https_proxy=${https_proxy} apt-get update && \
http_proxy=${http_proxy} https_proxy=${https_proxy} apt-get install -y --allow-unauthenticated google-chrome-stable && \
apt clean && rm -rf /var/lib/apt/lists/*
It's impossible to meet all requirements at once.
1) For example, 1 instance for chrome and 1 instance for safari but all tests will run before closing the browser.
You cannot install the Chrome and Safari web browsers on docker image. It's possible to install only Chromium and Firefox on it. See the Using TestCafe docker help topic for more information.
2) If a test fail, I want the screen shot taken and count number of test failed. But do want to continue.
TestCafe's Live mode works in the same way, but it's not available on docker.
This case you need to use Session Handling
During test execution, the Selenium WebDriver has to interact with the browser all the time to execute given commands. At the time of execution, it is also possible that, before current execution completes, someone else starts execution of another script, in the same machine and in the same type of browser.
more details

Categories