Getting the spec file name into TAP file - javascript

we use testem to run our javascript unit tests. As output I get a TAP file, that looks similar like this
ok 1 PhantomJS 2.1 - ABC Directive should contain a template
---
Log: |
{ type: 'log',
text: '\'WARNING: Tried to load angular more than once.\'\n' }
...
lets say, the test is defined ABCItemSpec.coffee. Is there anyway to include this file name in the final TAP output ?
I do not understand much about the javascript/gulp setup her, so the question might be too blurry, but maybe there is a general solution (the way to setup testem, or to give the spec file as argument etc) ?

Related

How to get all required modules from node.js as a single text file or string?

I need to get all files from some require stack and this include all requires inside the required too.
Example:
file.js
require("./b");
require("./c");
//require("./d"); // this is a comment, need to prevent that
AST
[{
path: "absolute_dir/b.js",
name: "7saf7fs6asf7" // hash
},
...]
ouput (with the AST i can get all files by his name and put them in one single file, like a bundler)
require("7saf7fs6asf7");
require("sa8d78as8d7f");
I don't know how to do this in a modular logic. PLZ help me :)

Managing multi sites in cypress

Following are the three country based sites I am having -
Site 1 - https://example.com/uk
Site 2 - https://example.com/fr
Site 3 - https://example.com/ie
All 3 sites are using same code base and on the basis of country (uk | fr | ie) in my code I am passing some default configuration, like country specific text and some feature enable/disable switch etc. to the inner pages.
In my cypress, I have created fixtures like -
/fixtures -
/uk
-uk-config.json
/fr
-fr-config.json
/ie
-ie-config.json
I am stuck with the folder structure in integration folder and do not know the recommended way of doing this. Please help me on this.
Option 1-
/integration -
/uk
-homepage.spec.js
-plp.spec.js
-pdp.spec.js
-cart.spec.js
/fr
-homepage.spec.js
-plp.spec.js
-pdp.spec.js
-cart.spec.js
/ie
-homepage.spec.js
-plp.spec.js
-pdp.spec.js
-cart.spec.js
Problem with this approach - Though this code is more segregated on country basis, but here lot of code duplicates and it get increases as we launch other country stores.
Option 2 -
/integration -
-homepage.spec.js
-plp.spec.js
-pdp.spec.js
-cart.spec.js
And in this pass, country specific configurations from fixtures. TBH, I don't know how can I manage this and it would really be good if someone find this is a better way and can provide some pointers toward this would really be helpful.
Problem:If I understood your problem clearly, you want to run your same set of tests but for different countries and you are facing issues in reading and there is a problem that suite gets increased if too many countries will be added just to test same set of tests. Right ??
Solution:
You can pass the COUNTRY variable as node env variable from command line and assign that as Cypress env variable and read it in your tests.
"test": "COUNTRY=$COUNTRY ./node_modules/.bin/cypress open --env COUNTRY=$COUNTRY"
Your run command should be like below
COUNTRY=fr npm run test
COUNTRY=in npm run test
COUNTRY=uk npm run test
COUNTRY=whatever npm run test
let json = require('config.json');
export const getCountryUrl = () => {
return json[Cypress.env().COUNTRY]['url']
}
{
"uk": {
"url": "https://uk-website"
},
"fr": {
"url": "https://fr-website"
}
}

Is it a bug in SonarQube's JavaScript plugin that it doesn't pick up Surefire test results of tests that are in a subdirectory?

I have a Surefire results directory with 2 files: TEST-Chrome_4202311135_Windows.dashboard.MonkeyTest.xml and TEST-Chrome_4202311135_Windows.PersonTest.xml. Thus, my tests have the following directory structure:
-tests
-PersonTest.js
-dashboard
-MonkeyTest.js
When I run Sonar Runner it picks up PersonTest.js but it says that dashboard/MonkeyTest.js doesn't exist:
18:24:58.747 WARN - Test result will not be saved for test class "dashboard.MonkeyTest", because SonarQube associated resource has not been found using file name: "dashboard/MonkeyTest.js"
Has anybody encountered this? Looks to me like a bug because the file is there.
Well, I've delved into the SonarQube's JavaScript Plugin code to debug it. Found the bug. Looks like this bug only happens on Windows. What the code does is iterates over all the test files, in my case "PersonTest.js" and "dashboard/MonkeyTest.js", and looks for the file "dashboard\MonkeyTest.js". But because "dashboard/MonkeyTest.js" does not equal to "dashboard\MonkeyTest.js" it ignores the results of this test. To be honest iterates over ALL the test files for every test result is inefficient to begin with. Below is the Java method. I'll try to get in contact with the author.
protected InputFile getTestFileRelativePathToBaseDir(String fileName) {
for (InputFile inputFile : fileSystem.inputFiles(testFilePredicate)) {
LOG.warn("Slava: '" + inputFile.file().getAbsolutePath() + "'");
if (inputFile.file().getAbsolutePath().endsWith(fileName)) {
LOG.debug("Found potential test file corresponding to file name: {}", fileName);
LOG.debug("Will fetch SonarQube associated resource with (logical) relative path to project base directory: {}", inputFile.relativePath());
return inputFile;
}
}
return null;
}

Sonarqube does not retrieve my JavaScript coverage from LCOV

I have an application with the following structure:
my-application
+- pom.xml
+- app
| +- scripts
| | +- app.js
| | +- **/*.js
| +- 3rd-party-libs
+- build
+- node_modules
+- test
I've create the pom.xml only to run the SonarQube analysis. Otherwise, all the tasks are run by Grunt (tests are run with Karma).
The content of the pom.xml is the following:
<properties>
<sonar.language>js</sonar.language>
<sonar.sourceEncoding>UTF-8</sonar.sourceEncoding>
<sonar.javascript.coveragePlugin>lcov</sonar.javascript.coveragePlugin>
<sonar.javascript.lcov.reportPath>build/karma/coverage/lcov.info</sonar.javascript.lcov.reportPath>
<sonar.exclusions>app/3rd-party-libs/**,node_modules/**</sonar.exclusions>
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
</properties>
<build>
<sourceDirectory>app/scripts</sourceDirectory>
<testSourceDirectory>test</testSourceDirectory>
</build>
When I run grunt test, it creates a build/karma/coverage/lcov.info that contains the following information:
TN:
SF:./app/scripts/app.js
FN:16,(anonymous_1)
FN:26,(anonymous_2)
FNF:2
...
After the SonarQube analysis, the dashboard shows a 0% code coverage.
I suspected that the path in the SF: was the source of the error. Thus, I've changed the sonar.javascript.lcov.reportPath property to use another lcov.info to test different values: app.js, ./app.js, app/scripts/app.js, ./app/scripts/app.js, but none worked, keeping the coverage to 0%.
What I am missing?
Just in case, I have the following configuration in my karma.conf.js:
coverageReporter: {
reporters: [
{
type: 'lcov',
dir: 'build/karma/coverage',
subdir: '.'
}
]
},
ps: Sonar version is 3.7.2, but I also tried on a 4.3, with the same results...
Edit: I've updated my configuration to use Sonar-runner directly, I'm using the latest version of Sonar (5.0.1) and JS plugin (2.3). I've also modified manually the lcov.info to have a "good" format (at least one format that matches the Sonar repo example):
SF:./app/scripts/app.js
DA:2,1
DA:20,1
DA:29,1
DA:34,1
end_of_record
SF:./app/scripts/services/exampleService.js
DA:1,1
DA:11,1
DA:12,0
end_of_record
The sonar-project.properties looks like:
sonar.projectKey=xxx
sonar.projectName=xxx
sonar.projectVersion=xxx
sonar.sourceEncoding=UTF-8
sonar.sources=app/scripts
sonar.tests=test
sonar.exclusions=app/3rd-party-libs/**,node_modules/**
sonar.dynamicAnalysis=reuseReports
sonar.language=js
sonar.projectBaseDir=.
sonar.javascript.coveragePlugin=lcov
sonar.javascript.lcov.reportPath=build/karma/coverage/lcov.info
And still, 0% of coverage :(
I was clueless, so I decided to modif the JavaScript plugin to add more logs. And I finally found the error, which is a vicious problem of... case sensitivity!
Let me explain. Let's consider the saveMeasureFromLCOVFile method of the CoverageSensor.java:
protected void saveMeasureFromLCOVFile(SensorContext context) {
String providedPath = settings.getString(JavaScriptPlugin.LCOV_REPORT_PATH);
File lcovFile = getIOFile(fileSystem.baseDir(), providedPath);
...
LOG.info("Analysing {}", lcovFile);
LCOVParser parser = new LCOVParser(fileSystem.baseDir());
Map<String, CoverageMeasuresBuilder> coveredFiles = parser.parseFile(lcovFile);
for (InputFile inputFile : fileSystem.inputFiles(mainFilePredicate)) {
try {
CoverageMeasuresBuilder fileCoverage = coveredFiles.get(inputFile.file().getAbsolutePath());
org.sonar.api.resources.File resource = org.sonar.api.resources.File.create(inputFile.relativePath());
if (fileCoverage != null) {
for (Measure measure : fileCoverage.createMeasures()) {
context.saveMeasure(resource, measure);
}
} else {
// colour all lines as not executed
LOG.debug("Default value of zero will be saved for file: {}", resource.getPath());
LOG.debug("Because: either was not present in LCOV report either was not able to retrieve associated SonarQube resource");
saveZeroValueForResource(resource, context);
}
} catch (Exception e) {
LOG.error("Problem while calculating coverage for " + inputFile.absolutePath(), e);
}
}
}
First, it reads the lcov.info file given to know for which files we have coverage data (retrieved by parsing the file, done with LCOVParser class).
After that, it takes the same file from the coveredFiles map to do the matching between metrics and code. If the file is not found (else part of the if (fileCoverage != null) {), then the code coverage is forced to 0.
That's what happened on my project.
So why is it happening? Simply because in my environment, inputFile is equals to d:\dev\my-application\app\scripts\app.js and in coveredFiles map, I have D:\dev\my-application\app\scripts\app.js. Note the difference of the case in the drive letter (d: against D:). As the map.get(...) is case sensitive, fileCoverage is null and then no coverage is calculated.
Now, I have to investigate on how I can force the path to have correct case...
After more investigation, I found a modification in the plugin code that works (at least for me, I didn't get into all the possible impacts). In LCOVParser, the filePath = CoverageSensor.getIOFile(moduleBaseDir, filePath).getCanonicalPath(); could be modified to filePath = CoverageSensor.getIOFile(moduleBaseDir, filePath).getAbsolutePath();, since the first one returns a path like D:\... while the second will return d:\....
In fact, I'm not even what is the preferred case to use on Windows. The following code:
public static void main(String[] args) throws IOException {
System.out.println("PATH 1 : " + new File(".").getAbsolutePath());
System.out.println("PATH 2 : " + new File(".").getCanonicalPath());
}
will return:
PATH 1 : D:\dev\preclosing\preclosing-eme\.
PATH 2 : D:\dev\preclosing\preclosing-eme
Anyway, I'm stuck for the moment, and I'm not even sure how to solve my issue without waiting for a JS plugin fix (since my "official" Sonar is a little bit old for the moment and only support JS plugin up to v2.1).

Nanoc rules file not handling my JavaScript directory

My nanoc content directory structure:
assets -> (css, images, files)
js
partials
[*.textile source files]
Extract from my rules file:
compile '/js/*/' do
# don’t filter or layout
end
.
.
.
route '/js/*/' do
item.identifier.chop + '.' + #item[:extension].to_s
end
Command line result:
Message:
RuntimeError: Found 2 content files for content/js/bootstrap; expected 0 or 1
Compilation stack:
(empty)
Stack trace:
0. /home/tomc/.rvm/gems/ruby-2.1.1/gems/nanoc-3.7.1/lib/nanoc/data_sources/filesystem.rb:168:in `block in all_split_files_in'
1. /home/tomc/.rvm/gems/ruby-2.1.1/gems/nanoc-3.7.1/lib/nanoc/data_sources/filesystem.rb:158:in `each_pair'
2. /home/tomc/.rvm/gems/ruby-2.1.1/gems/nanoc-3.7.1/lib/nanoc/data_sources/filesystem.rb:158:in `all_split_files_in'
3. /home/tomc/.rvm/gems/ruby-2.1.1/gems/nanoc-3.7.1/lib/nanoc/data_sources/filesystem.rb:86:in `load_objects'
4. /home/tomc/.rvm/gems/ruby-2.1.1/gems/nanoc-3.7.1/lib/nanoc/data_sources/filesystem.rb:45:in `items'
5. /home/tomc/.rvm/gems/ruby-2.1.1/gems/nanoc-3.7.1/lib/nanoc/base/source_data/site.rb:334:in `block in load_items'
6. /home/tomc/.rvm/gems/ruby-2.1.1/gems/nanoc-3.7.1/lib/nanoc/base/source_data/site.rb:333:in `each'
7. /home/tomc/.rvm/gems/ruby-2.1.1/gems/nanoc-3.7.1/lib/nanoc/base/source_data/site.rb:333:in `load_items'
8. /home/tomc/.rvm/gems/ruby-2.1.1/gems/nanoc-3.7.1/lib/nanoc/base/source_data/site.rb:244:in `load'
9. /home/tomc/.rvm/gems/ruby-2.1.1/gems/nanoc-3.7.1/lib/nanoc/base/source_data/site.rb:128:in `layouts'
... 27 more lines omitted. See full crash log for details.
I consulted How add own javascript file to nanoc?. I seem to be setting things up correctly, but my results say otherwise.
I cannot see the error. Anyone have any ideas?
Because of the way it maps input filenames onto output paths, Nanoc requires the base name (i.e., the filename less extension) of each file under content to be unique. From Nanoc's perspective you are giving it two files that share the base name bootstrap and thus cannot have unique output paths, so it gives you this error.
Since what you really want is to have Nanoc copy over this portion of your site (the third-party JavaScript files) verbatim, it'd be better to move these files out of the content tree altogether and set up a static data source from which to load them. Then Nanoc will simply copy the files over as-is without trying to process or rename them. The "Troubleshooting" page on the Nanoc website has instructions on how to do this; see "Solution #2" under "Error: “Found 3 content files for X; expected 0 or 1”.

Categories