How to get the value from selectbox? - javascript

I am trying to verify that correct option is selected from selectbox using protractor.
This is how I pick value from selectbox:
element(by.id('form-mileage-unit')).click().then(function() {
element(by.cssContainingText('option', browser.params.lengthUnit)).click();
});;
So base on this I write code below:
it('Verify paint color', function() {
element(by.id('form-mileage-unit')).click().then(function() {
element(by.cssContainingText('option', browser.params.lengthUnit).getAttribute("value")).toEqual(browser.params.lengthUnit);
});;
});
Unfortunately I am getting error:
TypeError: Object by.cssContainingText("option", "Motohodin") has no method 'getText'
Can someone advise me with this?

You are closing the parenthesis in the wrong place and there is no expect(). Replace:
element(by.cssContainingText('option', browser.params.lengthUnit).getAttribute("value")).toEqual(browser.params.lengthUnit);
with:
var option = element(by.cssContainingText('option', browser.params.lengthUnit));
expect(option.getAttribute("value")).toEqual(browser.params.lengthUnit);
If you are dealing with select->option constructions a lot, consider using an abstraction over it that would make your tests cleaner and more readable, see:
Select -> option abstraction

Related

getText is not a function error - Protractor (javascript)

I have node.js installed and protractor installed. I have experience with selenium-webdriver but Protractor is driving me nuts!!! I am also not that familiar with javascript.
This is what my code looks like:
describe('My app', function() {
var result = element(by.id('result-name'));
var enterBtn = element(by.id('enter'));
var clearFieldBtn = element(by.id('clear-field');
it('should bring up components on load', function() {
browser.get(`http://localhost:${process.env.PORT}`);
browser.wait(until.titleContains('Sample App'), 500);
browser.wait(until.presenceOf(browser.element(by.id('my-test-app'))), 500);
expect(enterBtn).isPresent;
});
it('result should equal username', function () {
browser.get(`http://localhost:${process.env.PORT}`);
expect(clearFieldBtn).isPresent;
expect(result.getText()).toEqual('John Smith'); //both tests pass without this line of code
});
});
The last line "expect(result.getText()).toEqual('John Smith');" throws me an error. I get:
expect(...).toEqual is not a function
Any help would be much appreciated. I have spent a couple of hours trying to find a solution and trying different things.
I also wanted to implement the isPresent function how it's done in the api docs which is like this: expect($('.item').isPresent()).toBeTruthy();
I tried to do:
expect(clearFieldBtn).isPresent().toBeTruthy();
But I get that isPresent is not a function...
The expect above that line seems poor. It should read
expect(clearFieldBtn.isPresent()).toBeTruthy();
not sure if that is causing the weird error on the line below...just thought I would throw it out there. All your protractor APIs need be be called within the expect because isPresent is not a attribute of expect
Have you tried these lines:
clearFieldBtn.isPresent().then(function(bln) {
expect(bln).toBe(true);
});
result.getText().then(function(tmpText) {
expect(tmpText).toBe('John Smith');
});
If you still get an error on result.getText(), please check the presence of the result object.

jQuery Plugin public methods not working when applied to multiple elements

I posted a similar issue earlier, but it was flagged as a duplicate. However, this referenced article did not answer my question, so I'll try this again, this time using the solution of said article in my example.
The solution provided in this article creates the same issue I had before: when there is more than one element, I cannot call any of the public methods of the plugin.
Since no working example was provided, let's start with the code the article gave:
(function($){
$.fn.myPlugin = function(options) {
// support multiple elements
if (this.length > 1){
this.each(function() { $(this).myPlugin(options) });
return this;
}
// private variables
var pOne = '';
var pTwo = '';
// ...
// private methods
var foo = function() {
// do something ...
}
// ...
// public methods
this.initialize = function() {
// do something ...
return this;
};
this.bar = function() {
// do something ...
};
return this.initialize();
}
})(jQuery);
I LOVE the internal loop so that it's applied to each instance of the element, but I feel the repeated "return this" is redundant. I think if we removed every single one of them, this plugin would work exactly the same. But, for the sake of argument, I'm going to leave them in my working example.
As you can see in this jsfiddle example, it works fine when there is only one element. The public method runs fine.
However, if I were to comment the other 4 elements back in like here, it throws an error in the console: "undefined is not a function". This, of course, makes sense since I'm attempting to run the public method on a reference to all elements on not an individual element.
Well, then I use .eq(0) to run the method only on the first instance of the element here, but I get the exact same error in the console.
So, why isn't calling the public method on the individual element working? Is this a scoping issue?
Please advise. Thanks!
Ok, so I think I've answered my own question. The issue is that I'm not applying a jQuery plugin to a DOM element. I'm applying it to a jQuery element. So, if I were to apply the jQuery plugin to a jQuery element, referenced like $element or $('.element'), I can then run any public methods because the scope is the same. But, if I were to reference it in a different way, like say $parentelement.eq(0), I'm using a difference reference, one that did not get the plugin applied to it, so naturally, it would not have the defined method. I think I'm getting the concept right. Still a little shaky on this. Maybe someone else can explain it better.
Nevertheless, while the above code does technically work, public methods are not practical on a jQuery plugin. I suggest instead using a Custom Event to make the jQuery plugin do something. Like this:
(function($) {
$.fn.extend({
myTestPlugin: function() {
if (this.length > 1) {
this.each(function() { $(this).myTestPlugin(); });
}
this.done = function() {
$(this).html('Done!');
};
var alsoDone = function() {
$(this).html('Also done!');
};
this.html('Replace me!');
this.on('alsoDone', alsoDone);
}
});
})(jQuery);
Here is an example where I am using trigger to make the plugin do something on an individual element, which works, but the method still fails as expected.
I hope this helps other people with similar issues.

How do I get Jasmine to always show the spec list?

If my Jasmine test has failures, it only shows those by default. I have to click "Spec List" to see all of the tests that were run.
Can I somehow get it to always show the spec list by default?
I am using jasmine 2.1.3 with require.js as outlined in this stackoverflow question:
Getting requirejs to work with Jasmine
and this was bugging me too.
I am also using jquery so I added an event trigger after the .execute() like so:
require(specs, function (spec) {
jasmineEnv.execute();
$('.spec-list-menu').click();
});
I couldn't find any configuration for setting the default, but you can see in the jasmine-html.js file:
find('.failures-menu').onclick = function() {
setMenuModeTo('failure-list');
};
find('.spec-list-menu').onclick = function() {
setMenuModeTo('spec-list');
};
setMenuModeTo('failure-list');
if you changed it to:
find('.failures-menu').onclick = function() {
setMenuModeTo('failure-list');
};
find('.spec-list-menu').onclick = function() {
setMenuModeTo('spec-list');
};
setMenuModeTo('spec-list');
It will also set the default.
I don't really like editing libraries like that since I usually forget what I have changed when I update the library.
That was the reason I went with the jquery route.

RobinBrouwer WMD - Reading Basic jQuery

I'm new to jQuery (and truth be told I am only using it because this WMD editor requires it).
Anyway, I am looking at the jQuery code (go to the above link and view jquery.wmd.js) and there are option defaults:
WMDEditor.defaults = { // {{{
version: 2.0,
output_format:"markdown",
lineLength:40,
button_bar: "wmd-button-bar",
preview: "wmd-preview",
output: "wmd-output",
input: "wmd-input",
...
Which leads me to believe that there is a way to pass on the options as arguments to the function. I am looking for a way to pass on the helpLink option. I am sure it is really easy, like facepalm easy, but I can't read jQuery and there is no documentation. Can someone show me how to pass on option arguments to this
$(function() {
$(".wmd-input").wmd();
});
If the plugin is setup normally you can do this:
var defaults = {
version: 2.0,
output_format:"markdown",
lineLength:40,
button_bar: "wmd-button-bar",
preview: "wmd-preview",
output: "wmd-output",
input: "wmd-input"
// and then keep on going
}
$(function() {
$(".wmd-input").wmd(defaults);
});

How to return $(this)

I'm using jQuery and made a plugin for some in house work that basically builds URLs for our internal API. Anyways, I want to return $(this) and im not getting the right thing and im getting a createdocumentfragment error?
Plugin code:
$.get(base_url,{
agenda_id:defaults.id,
action:defaults.action+defaults.type,
output:defaults.output
},function(html){
defaults.callback(html);
});
That works fine, but i want to add return obj like so:
$.get(base_url,{
agenda_id:defaults.id,
action:defaults.action+defaults.type,
output:defaults.output
},function(html){
defaults.callback(html);
return obj;
});
Obj is set at the start of my plugin and obj works fine throughout the plugin. It's set as obj=$(this);
In my script, which uses the plugin, I have:
$('#agenda-live-preview').agenda({action:'get',type:'agenda',id:window.location.href.split('/').pop(),callback:function(html){
$(this).empty().append($(html).html());
}});
However, it doesn't work and returns:
Error: doc.createDocumentFragment is not a function
Source File: http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js
Line: 4373
In the console error logs. Any ideas how to return $(this) AND run the callback?
I (finally) left a comment in your other question. :o) I'm pretty sure you need to do this in your plugin:
defaults.callback.call(this,html);
instead of:
defaults.callback(html);
It sounds like you want to return the object to the original caller.
agenda = function(opts, callback) {
$.get(base_url,{
agenda_id:defaults.id,
action:defaults.action+defaults.type,
output:defaults.output
},function(html){
defaults.callback(html);
});
return obj;
}
I'm guessing the idea is to enable chaining, so that you can say something like
$('#id').agenda(opts).show();
or whatever. Of course, this will execute just after the $.get is issued and not after it is completed, but this is normal and probably what you want.

Categories