Protractor: One test passes, but the other fails - javascript

I want to check two things - whether the search functionality works on AskJeeves AND whether the search boxes stored the right string.
To check this I run three expect statements:
expect(searched_term.getText()).toEqual('Baking a Cake without Margarine');
expect(searched_term.getText()).toEqual('Baking a Pie without Butter');
expect(searched_term.getText()).toEqual(search_box.getText());
Only the second one should fail. But the first one fails as well. Why is that? Here is the error log. Also how can I count how many expect statements I have and console.log() output that?
Error Log:
browser.waitForAngularEnabled(false);
describe('Enter Search Query in Ask Jeeves', function() {
it('This will insert a query', function() {
browser.get(browser.baseUrl);
element(by.xpath('//*[#id="search-box"]'));
var search_box = element(by.name("q")).sendKeys('Baking a Cake without Margarine');
browser.pause(1500);
var button = element(by.xpath('//*[#id="sbut"]'));
button.click();
var searched_term = element(by.name("q"));
expect(searched_term.getText()).toEqual('Baking a Cake without Margarine');
expect(searched_term.getText()).toEqual('Baking a Pie without Butter');
expect(searched_term.getText()).toEqual(search_box.getText());
// This expect statement checks if the term in the following page reflects the term originally searched.
// In addition this will check functionality of the search engine.
browser.pause(1500);
});
});

The searched_term element is an input element - it does not have a "text" and the value of the input is stored in the value attribute. Replace getText() with getAttribute("value"):
expect(searched_term.getAttribute("value")).toEqual('Baking a Cake without Margarine');

Related

Code Mirror Get Current Line Number every time content changes

I am trying to use Code Mirror to create a text editor. I want to show the current line number to the user at the bottom of the display, as text editors do.
So far I have tried this:
function updateInfo(){
var lines = editor.lineCount();
document.getElementById('line-no.').innerText = lines;
editor.refresh();
}
editor.on("change", updateInfo());
The line-no. is a span where I want to display the Line Number. This works for the first Line Number but then when I go to some other line, it doesn't do anything. The console shows this error:
codemirror.js:2154 Uncaught TypeError: Cannot read property 'apply' of undefined
at codemirror.js:2154
at fireCallbacksForOps (codemirror.js:2111)
at finishOperation (codemirror.js:2125)
at endOperation (codemirror.js:3747)
at HTMLTextAreaElement.<anonymous> (codemirror.js:3884)
Update
To follow updates in the editor, register a handler on the cursorActivity event. This event is fired when there is a change in the cursor or selection. The handler is called with the instance of CodeMirror; on this you can call the getCursor method to be the an object that contains the current line number that the cursor is active on.
Note that the line number is zero-based, so you may or may not increment it by 1.
const STATUS_CURRENT_LINE = document.getElementById('line-no.');
const onCursorActivity = (instance) => {
const cursor = cm.getCursor();
STATUS_CURRENT_LINE.textContent = cursor.line + 1;
}
editor.on("cursorActivity", onCursorActivity);
Setting the current line number when there is a doc change in the editor
The error happens because the updateInfo callback is called even before you register it. So that the value registered as the callback is undefined.
editor.on('change', updateInfo()) // -> editor.on('change', undefined)
This can be resolved by registering the function.
editor.on('change', updateInfo)
However, the signature for the callback should follow what is documented.
The change callback is passed the instance of CodeMirror and a changeObject from which you can retrieve the current line.
"change" (instance: CodeMirror, changeObj: object)
Fires every time the content of the editor is changed. The changeObj is a {from, too, text, removed, origin} object containing information about the changes that occurred as the second argument. from and to are the positions (in the pre-change coordinate system) where the change started and ended (for example, it might be {ch:0, line:18} if the position is at the beginning of line #19). text is an array of strings representing the text that replaced the changed range (split by line). removed is the text that used to be between from and to, which is overwritten by this change. This event is fired before the end of an operation before the DOM updates happen.
const STATUS_CURRENT_LINE = document.getElementById('line-no.');
function updateInfo(instance, changeObj){
STATUS_CURRENT_LINE.innerText = changeObj.to.line;
}
editor.on("change", updateInfo);

I attached an onClick prompt to an SVG image, but i cant get the prompt to run a jQuery if else statement

I'm making an SVG map of the US most of it is done so far, its all down to a simple if else statement so that i can finish. The goal is if i click on a state (i have the path and id for every state) a prompt will pop up asking for state name. The jQuery code is then supposed to fill the state green if answer i put into the prompt is correct, and red if incorrect. It does fill red when i enter something into the prompt, however it does this every time, even when the prompt is correct. How can i fix this please i need a quick answer by today.
Here is the jsfiddle https://jsfiddle.net/vnqcyu90/
jQuery(function($) {
$('path').click(function() {
prompt("Enter State Initials")
if ($('path id') == prompt) {
this.style.fill = "green";
} else {
this.style.fill = "red";
}
});
});
that's the specific line of code causing me issues, it both adds the onclick function to the SVG map, as well as handle the if else statement related to the prompt asking the name of the state which in my case is the path id. (This code is jQuery 1.7.1)
There are several problems with your code.
First, you are not assigning the result of Window.prompt() to anything. You need to do:
var prompt = window.prompt("Enter State Initials");
The next problem is your jQuery selector
$('path id')
jQuery selectors return a list of elements that match your selector string. In this case, you are asking it to return all elements named "id" (ie. <id>) who have an ancestor <path> element.
If you want to check the id value of the path you click on, then what you need to do is:
$(this).get(0).id
$(this) turns the clicked element into a jQuery object. The get(0) gets the first element of the jQuery object (remember jQuery selectors always return a list). In this case however, there will only ever be one element in the list.
And you get read the id attribute of the element simply by referencing the id property of the element.
So your final code would look like:
var prompt = window.prompt("Enter State Initials")
if ($(this).get(0).id == prompt) {
this.style.fill = "green";
} else {
this.style.fill = "red";
}
Since all your state ids are uppercase, you'll probably also want to convert the text people type in. For example:
var prompt = window.prompt("Enter State Initials").toUpperCase();
Updated fiddle

How can I check if the user input with the database information?

I have a JavaScript programme that randomly selects an image of an object from the database and display that image to the user. The image is saved with the object name (i.e. apple.gif)
I am using the following code in order to check whether the user input response is the correct answer to the test or not:
However the code does not do anything. Could anyone let me know what the problem is please?
Look at your JavaScript console:
Uncaught ReferenceError: random_image_array is not defined
You made a typo. When you defined the variable you said images (with an s).
function checkUserInput() {
var userInput = document.getElementById("textInput").value;
var stringToCheckAgainst = random_image_array[num].split('.');
//this splits the item at the array index into an array, like so. If the item is "apple.gif", the array reads ["apple", "gif"]
if (userInput == stringToCheckAgainst[0]) {
//user has inputted the correct string
document.write("Correct!");
} else {
//user has inputted an incorrect string
document.write("Incorrect response!");
}
}
The above is a function. In order to use the function, you must call it.

Generate multiple checkboxes from Javascript array?

My jsfiddle will help explain things better than I ever can >< http://jsfiddle.net/L65QD/17/
I've got two select boxes, when you select something from the first select it enables the second. I have quite a few arrays that I'm using as sort of a fake database.
What I need to happen is that depending on what is selected in profile_select it needs to generate checkboxes for every PRIVILEGE_CODE it has, however the checkboxes must be generated with SEC_PRIVILEGES.Name next to them instead of the actual PRIVILEGE_CODE and they must be generated in the correct DIV. Since it's so hard to explain I made a JSFiddle which just about summarizes it http://jsfiddle.net/L65QD/17/
If my instructions aren't clear:
Depending on what profile is selected in the PROFILE_SELECTION
Needs to generate some checkboxes based on what PRIVILEGE_PROFILES.PRIVILEGE_CODES it has
However the checkboxes must have the name from SEC_PRIVILEGES next to them instead of the code, so PRIVILEGE_CODES = Unique_Code
Checkboxes are generated in either the DA div or the MR div based on what Group_Code they have in SEC_PRIVILEGES (this bit really confuses me, can you make it so a DIV ID can be equal to something from an array?) However to generate them in DA or MR it can't really be an IF because my fiddle is just an example and I'd actually have about 30 different codes so I couldn't do 30 IF statements.
This is the method I was experimenting with but it doesn't really make sense and is probably not even close to being on the right lines:
$(document).on('change', '#select_profile', function () {
var Select = $("#select_profile option:selected").text();
$("#apps").html;
for (var i = 0; i < SEC_Privileges.length; i++) {
if (SEC_Privileges[i].Unique_Code == //something?) {
$('#DA').html("<b>lol</b>");
}
}
});
So that's pretty simple:
Correct this fatal error: Array literals are written in square bracket notation ([], not ()). When you log the PRIVILEGE_PROFILE[0].PRIVILEGE_CODE you'll see only the first code is logged as the key's value.
Building the function: Consider what you need:
When a user changes company, all checkboxes must be reset
When a user changes profile, all checkboxes must be reset, then changed accordingly
When 'None' is selected in either dropdown, all checkboxes must be reset
Result: http://jsfiddle.net/kevinvanlierde/L65QD/19/
Some conventions:
Please choose one naming convention and stick with it. The more common ones are lowercase_underscore or CamelCase. You can opt for uppercase, but don't mix them (easier readability). I've had several errors just because I wrote the names incorrectly.
Declare your variables at the start of your function, assign them further on.
Also want to add that if I were to have control over the object's structure, I would probably opt for a more hierarchical tree/ JSON-like structure, eg instead of your current object, do:
var SEC_Privileges = {
'DA': {
'name': 'Dispatch App',
'accesses': {
'DAAccess': 'Access',
'DASuper': 'Supervisor'
}
},
'MR': {
'name': 'MyRoster',
'accesses': {
'MRAccess': 'Access',
'MRSuper': 'Supervisor'
}
}
}
Because the object keys are themselves values, you can use them to build your UI, eg to get the full name of your MRAccess you could do something like SEC_Privileges.MR.name + SEC_Privileges.MR.accesses.MRAccess to get MyRoster Access
There is different ways to approach this but the amount of Privileges would always be the same?. Depending on what your SEC_privileges is if its JSON array then you could loop through that array and access the code and the description. You would then want to validate the selected privileges again the whole set and say something like:
var array = ('one','two','three');
if($.inArray(SEC_privileges[i].Unique_code, array))
{
$('#DA').html("<input type='checkbox' id='"+i+"' value='"+SEC_privileges[i].Unique_code+"' checked/>"+SEC_privileges[i].Unique_desc);
}
else
{
$('#DA').html("<input type='checkbox' id='"+i+"' value='"+SEC_privileges[i].Unique_code+"'/>"+SEC_privileges[i].Unique_desc);
}
A ticked value is done by adding the word checked as part of the html input object. Like illustrated above

How to ensure the 'correct' variable is used in a loop with anonymous functions?

We have followed Tom Anthony's tutorial to calculate a geocode from a UK postcode to plot a marker on a Google Map. This has worked fine, but now we wish to add a popup when you click on a location. So we updated our function to place a marker and original usePointFromPostcode code to take in a description:
function usePointFromPostcode(postcode, description, callbackFunction) {
localSearch.setSearchCompleteCallback(null,
function() {
if (localSearch.results[0]) {
var resultLat = localSearch.results[0].lat;
var resultLng = localSearch.results[0].lng;
var point = new GLatLng(resultLat,resultLng);
callbackFunction(point, description);
}else{
alert("Postcode not found!");
}
});
localSearch.execute(postcode + ", UK");
}
// loop through the array of postcodes to output markers
for(var i=0; i<postcodes; i++) {
usePointFromPostcode(postcodes[i], descriptions[i], placeMarkerAtPoint);
}
However, whilst the page loads without error, the markers all have the same description - that of the last item in the array. I believe this is due to a closure, or rather a lack of one, but am unable to hack out the solution. How can we get the descriptions in sync with the points?
If localsearch.execute initiates a search but returns before the search is complete, then that would explain the behaviour. Two possible solutions. Create a separate GlocalSearch object for each query or delay issuing the second query until the first is complete, etc.
I don't know enough about the GlocalSearch class to say if the former is sensible. If it is, you presumably will have several searches running in parallel that may finish in arbitrary order.
To do the later: Alter your callback to set a global flag done to true. Before initiating the first search, set done to false. After initiating the first search, set a timeout. The code executed by the timeout does the following: if done is now true, it sets done to false and initiates the second search. Otherwise, it simply repeats the same timeout. And of course this sort of thing repeats until all searches are complete, at which point the time out code initiates whatever you want to do after that loop. See http://www.ehow.com/how_4847411_simulate-whilesleep-loop-javascript.html for a short article that may be helpful.

Categories

Resources