Jasmine2: get current spec name - jasmine

In Jasmine 1.3, we had this option to the get current spec and suite names:
describe("name for describe", function () {
it("name for it", function () {
console.log(this.suite.getFullName()); // would print "name for describe"
console.log(this.description); // would print "name for it"
});
});
This does not longer work in Jasmine 2.x.
Anyone knows how to fetch those?
Thanks.

I add a new jasmine reporter, then get the spec name without define N variable on each spec. Hope can help, thanks.
var reporterCurrentSpec = {
specStarted: function(result) {
this.name = result.fullName;
}
};
jasmine.getEnv().addReporter(reporterCurrentSpec);

The reason this no longer works is because this is not the test. You can introduce a subtle change to your declarations however that fix it. Instead of just doing:
it("name for it", function() {});
Define the it as a variable:
var spec = it("name for it", function() {
console.log(spec.description); // prints "name for it"
});
This requires no plug-ins and works with standard Jasmine.

As far as Jasmine 2 is concerned currentSpec is discontinued on purpose. However there is a custom plugin/library developed that is based on jasmine reporter plugin which you can use. Here's the Link. Hope it helps with your requirement.
Its very simple to use, install the package with npm command -
npm install -g jasmine-test-container-support
Get the test container support by writing below lines before your describe or test suite -
var JasmineTestContainerSupport = window.JasmineTestContainerSupport || require('jasmine-test-container-support');
JasmineTestContainerSupport.extend(jasmine);
Later use the test container in your spec's to get its description -
var specDesc = jasmine.getEnv().getTestContainer();
Hope this helps.

var currentSpecName = describe('Test1', function() {
var currentStepName = it("Step1", function(){
console.log(currentStepName.description); // Prints It Name
console.log(currentSpecName.getFullName()); //Prints Describe Name
});
});

This worked for me in jasmine 3.5+
I know this is a relatively old question but found something which worked for me
describe('Desc1',() => {
afterEach(() => {
const myReporter = {
specDone: (result) => {
console.log('Spec FullName: ' + result.fullName);
console.log('Spec Result: ' + result.status);
}
};
jasmine.getEnv().addReporter(myReporter);
});
})
Credit for the solution : https://groups.google.com/g/jasmine-js/c/qqOk6Nh7m4c/m/Nyovy2EjAgAJ

This is probably a bit late but you can get the suite name outside the spec.
Please try the following code:
describe("name for describe", function () {
console.log(this.getFullName()); // would print "name for describe"
it("name for it", function () {
//Your test spec
});
});

Related

Jasmine mock window.location.reload(true);

I have a constructor of a js object that looks like this:
function SomeThing(window, document) {
var self = this;
self.window = window;
self.document = document;
if (!self.window.sessionStorage.getItem('page-reloaded')) {
self.window.sessionStorage.setItem('page-reloaded', true);
self.window.location.reload(true); // PROBLEM ON THIS LINE
return;
}
}
my mock test looks like this:
beforeEach(function() {
mockWindowObj = {
'location': {
'href': '',
'search': '?hello=world',
'pathname': '/some/path',
'replace': function () {},
'reload': jasmine.createSpy()
}
};
spyOn(mockWindowObj.location, 'reload').and.callFake(function(){}); ;
some = new SomeThing(mockWindowObj, mockDocumentObj);
});
When I run a test I get this error:
PhantomJS 2.1.1 (Mac OS X 0.0.0) ERROR
{
"message": "Some of your tests did a full page reload!",
"str": "Some of your tests did a full page reload!"
}
If I comment out the line window.location.reload(true) all of my test run fine and pass. I'm sort of new to unit tests and I'm not sure how to get around this. Any help would be very much appreciated. Thanks in advance.
Your posted code cannot be what you actually ran. The line containing self.window.sessionStorage.getItem would have to fail since you did not define sessionStorage on your mock.
I guess the SomeThing function is being called with window pointing to the real window object. That explains what you observe.

Get currently executed describe/test name

Is it possible with Jest (Jasmine) to get the currently executed name of the test or describe inside the test?
Using Jasmine: How to get name of current test is not working anymore, at least with Jest.
e.g.
test('Error missing body', (done) => {
console.log('Currently executing: ' + REFERENCE_TO_TEST_NAME);
done();
});
Thanks
From this thread:
console.log(expect.getState().currentTestName);
Worked for me.
The tests are supposed to contain only the basic code for your test: Arrange / Act / Assert, so it's not a good practice to introduce this kind of code at this place. But if you want to log the currently running test, you can use the custom_reporter API: https://jasmine.github.io/2.1/custom_reporter.html
You can get the same result that you expect by adding this code:
jasmine.getEnv().addReporter({
specStarted: function(result) {
console.log(`Spec name: ${result.fullName}, description: ${result.description}`);
}
});
you can try:
let spec = test('Error missing body', (done) => {
console.log('Currently executing: ' + spec.getFullName());
done();
});
const testParam = 'any text you need';
describe(`${testParam}`, () => {
test('mind the backtick', () => {
console.log(`Currently executing: ${testParam}`);
});
});

How can I test that an element does not exist on the page with Protractor?

I am trying to test if an element is not present on a page.
I have tried using the following method, but I get an error each time:
Method:
expect(element(CastModule.PersonXpath).isDisplayed()).toEqual(false);
Error: Failed: Timed out waiting for Protractor to synchronize with the page after
seconds. Please see https://github.com/angular/protractor/blob/master/docs/f ...
What method do you recommend?
The error should not be related to the checking for the absence of an element. Try the following:
var elm = element(CastModule.PersonXpath);
expect(browser.isElementPresent(elm)).toBe(false);
See also:
In protractor, browser.isElementPresent vs element.isPresent vs element.isElementPresent
Yeah, testing for NOT visible can be sucky. You should be able to use isPresent(), which means in the dom, where isDisplayed() means it's actually visible, which I'm thinking is your issue. Try...
expect(element(CastModule.PersonXpath).isPresent()).toEqual(false);
You may also want to break this out into a method and use an Expected Condition.
The error doesn't look like it's to do with the element being displayed. It looks like it's to do with page synchronization. Try ignoring the sync, then waiting for angular above the expect with:
browser.ignoreSynchronization = true;
browser.waitForAngular();
expect(element(CastModule.PersonXpath).isDisplayed()).toEqual(false);
To check for visibility (in case isDisplayed or isPresent isn't working), just use:
if (!EC.invisibilityOf(ug.personXpath)) {
throw new Error("Partner logo is not displayed");
}
I managed to find out a solution, using the protractor library.
var EC = protractor.ExpectedConditions; browser.wait(EC.invisibilityOf(element(by.xpath(CastModule.PersonXpath))), 5000).then(function() {
if (EC.invisibilityOf(element(by.xpath(x.LanguagesXpath)))) {
console.log("Persons module is not present - as expected for this scenario");
} else {
throw new Error("Element STILL present");
}
});
});
You can also try below code to handle element displayed or not. Below code returns true or false according to the visibility of the element.
browser.wait(() => {
return element(by.className("claasName")).isDisplayed()
.then(
(hasDisplayed) => {
console.log("Has displayed: "+ hasDisplayed);
return hasDisplayed === false;
}
);
}, 5000)
.then(
() => {
return true;
},
() => {
return false;
}
)
To use presence of element use:
var elm = element(CastModule.PersonXpath);
elm.isPresent().then(function (present) {
if (present) {
element(CastModule.PersonXpath).then(function (labels) {
});
} else {
console.log('Element did not found');
}`enter code here`
expect(elem.isNull===undefined).to.be.equal(true);

Skipping a test in Qunit

I just found qHint, a method to integrate jsHint testing into Qunit... but it doesn't work locally (I don't mean localhost) except in Firefox.
So I wanted to add a "warning" or "notice", NOT a test failure, showing that the test was skipped:
// do unit test if not local or local and running Firefox
t = QUnit.isLocal;
if (!t || (t && /Firefox/.test(navigator.userAgent))) {
jsHintTest('JSHint core check', 'js/myplugin.js');
} else {
test('JSHint core check (skipped)', function(){
ok( true, 'check not done locally' );
});
}
I would just like to make it more obvious that a test was skipped, is this possible?
Update: Thanks to Odi for the answer!, but I had to make a slight modification to make the code work in QUnit v1.11.0pre:
QUnit.testSkip = function( testName, callback ) {
QUnit.test(testName + ' (SKIPPED)', function() {
if (typeof callback === "function") {
callback();
}
var li = document.getElementById(QUnit.config.current.id);
QUnit.done(function() {
li.style.background = '#FFFF99';
});
});
};
testSkip = QUnit.testSkip;
I had the same requirement and I simply defined a new kind of test() that I called testSkip().
This test method simply replaces your test function and changes the name to <test name> (SKIPPED). After that the test is considered passed by QUnit.
To further indicate that this is a skipped test, I added a callback function to QUnit.done for each skipped test to change the color of the test in the HTML output to yellow. These callbacks are executed when the test suite is done. Setting the value directly does not work, because QUnit applies the styles for passed/failed tests at the end of the run.
QUnit.testSkip = function() {
QUnit.test(arguments[0] + ' (SKIPPED)', function() {
QUnit.expect(0);//dont expect any tests
var li = document.getElementById(QUnit.config.current.id);
QUnit.done(function() {
li.style.background = '#FFFF99';
});
});
};
testSkip = QUnit.testSkip;
Then you can use testSkip() instead of test() for skipped tests.
For my test suite the result looks like that:
For anyone who may have glazed over the comments, Mottie's comment on the question points out that Qunit now has a skip() function. Just replace any call to test() with skip() to skip that test.

How do I focus on one spec in jasmine.js?

I have a bunch of failing specs from a rather large architectural change. I'd like to work on fixing them one by one by tagging each one with 'focus'.
Does jasmine.js have a feature like this? I swore I read at one point that it does but I don't see it in the docs.
When using Karma, you can enable only one test with fit or fdescribe (iit and ddescribe in Jasmine before 2.1).
This only runs Spec1:
// or "ddescribe" in Jasmine prior 2.1
fdescribe('Spec1', function () {
it('should do something', function () {
// ...
});
});
describe('Spec2', function () {
it('should do something', function () {
// ...
});
});
This only runs testA:
describe('Spec1', function () {
// or "iit" in Jasmine prior 2.1
fit('testA', function () {
// ...
});
it('testB', function () {
// ...
});
});
In core since 2.1 with fit and fdescribe.
You can run a single spec by using the url for the spec
describe("MySpec", function() {
it('function 1', function() {
//...
})
it('function 2', function() {
//...
}
})
Now you can run just the whole spec by this url http://localhost:8888?spec=MySpec and a the first test with http://localhost:8888?spec=MySpec+function+1
There are a few ways you can do it.
There is: Jasmine's feature Focused Specs (2.2): http://jasmine.github.io/2.2/focused_specs.html
Focusing specs will make it so that they are the only specs that run. Any spec declared with fit is focused.
describe("Focused specs", function() {
fit("is focused and will run", function() {
expect(true).toBeTruthy();
});
it('is not focused and will not run', function(){
expect(true).toBeFalsy();
});
});
However, I don't really like the idea of editing my tests (fit and fdescribe) to run them selectively. I prefer to use a test runner like karma which can filter out tests using a regular expression.
Here's an example using grunt.
$ grunt karma:dev watch --grep=mypattern
If you're using gulp (which is my favourite task runner), you can pass args into gulp-karma with yargs and match patterns by setting karma's config.
Kinda like this:
var Args = function(yargs) {
var _match = yargs.m || yargs.match;
var _file = yargs.f || yargs.file;
return {
match: function() { if (_match) { return {args: ['--grep', _match]} } }
};
}(args.argv);
var Tasks = function() {
var test = function() {
return gulp.src(Files.testFiles)
.pipe(karma({ configFile: 'karma.conf.js', client: Args.match()}))
.on('error', function(err) { throw err; });
};
return {
test: function() { return test() }
}
}(Args);
gulp.task('default', ['build'], Tasks.test);
See my gist: https://gist.github.com/rimian/0f9b88266a0f63696f21
So now, I can run a single spec using the description:
My local test run: (Executed 1 of 14 (skipped 13))
gulp -m 'triggers the event when the API returns success'
[20:59:14] Using gulpfile ~/gulpfile.js
[20:59:14] Starting 'clean'...
[20:59:14] Finished 'clean' after 2.25 ms
[20:59:14] Starting 'build'...
[20:59:14] Finished 'build' after 17 ms
[20:59:14] Starting 'default'...
[20:59:14] Starting Karma server...
INFO [karma]: Karma v0.12.31 server started at http://localhost:9876/
INFO [launcher]: Starting browser Chrome
WARN [watcher]: All files matched by "/spec/karma.conf.js" were excluded.
INFO [Chrome 42.0.2311 (Mac OS X 10.10.3)]: Connected on socket hivjQFvQbPdNT5Hje2x2 with id 44705181
Chrome 42.0.2311 (Mac OS X 10.10.3): Executed 1 of 14 (skipped 13) SUCCESS (0.012 secs / 0.009 secs)
[20:59:16] Finished 'default' after 2.08 s
Also see: https://github.com/karma-runner/karma-jasmine
For anyone stumbling upon this, a better approach, which you can set up from the code itself, is to use this plugin: https://github.com/davemo/jasmine-only
It allows you set the spec exclusivity right on the code like this:
describe.only("MySpec", function() {
it('function 1', function() {
//...
})
it.only('function 2', function() {
//...
}
})
// This won't be run if there are specs using describe.only/ddescribe or it.only/iit
describe("Spec 2", function(){})
There has been a long discussion to get this added to Jasmine core, see: https://github.com/pivotal/jasmine/pull/309
If you happen to be using Jasmine via Karma/Testacular you should already have access to ddescribe() and iit()
You can create your all your specs up front but disable them with xdescribe and xit until you're ready to test them.
describe('BuckRogers', function () {
it('shoots aliens', function () {
// this will be tested
});
xit('rescues women', function () {
// this won't
});
});
// this whole function will be ignored
xdescribe('Alien', function () {
it('dies when shot', function () {
});
});
This is the most simplified answer with a practical example .Even in fdescribe you can run few it blocks using it. f means focus.
Also in a none fdescribe block which is just describe, you can select only specific it blocks by marking them as fit.
Please run the below code and observe the console log, also read the comments in the code.
Read this author's article it helps too . https://davidtang.io/2016/01/03/controlling-which-tests-run-in-jasmine.html
//If you want to run few describe only add f so using focus those describe blocks and it's it block get run
fdescribe("focus description i get run with all my it blocks ", function() {
it("1 it in fdescribe get executed", function() {
console.log("1 it in fdescribe get executed unless no fit within describe");
});
it("2 it in fdescribe get executed", function() {
console.log("2 it in fdescribe get executed unless no fit within describe");
});
//but if you and fit in fdescribe block only the fit blocks get executed
fit("3 only fit blocks in fdescribe get executed", function() {
console.log("If there is a fit in fdescribe only fit blocks get executed");
});
});
describe("none description i get skipped with all my it blocks ", function() {
it("1 it in none describe get skipped", function() {
console.log("1 it in none describe get skipped");
});
it("2 it in none describe get skipped", function() {
console.log("2 it in none describe get skipped");
});
//What happen if we had fit in a none fdescribe block will it get run ? yes
fit("3 fit in none describe get executed too eventhough it;s just describe ", function() {
console.log("3 fit in none describe get executed too");
});
});
With stand-alone Jasmine(2.0.0), on the spec_runner.htlm, I could click a specific spec and focus on that one spec. I should have noticed this feature earlier.
Not exactly what you've asked for but adding iit will test only that particular spec and ignore all others in the file, ddescribe works in the same way. So you can focus on a particular spec using iit or ddescribe

Resources