Trouble hiding a div within a template literal using jQuery - javascript

I've written this bit of jQuery code in Oxygen Builder's JavaScript element to query the job board API and return an array of departments and their jobs. I'm testing to see if the department[0].jobs.length returns 0 then hide the #job-list div, otherwise show it and its associated jobs. The code succeeds in querying the API and returning 0 jobs but the remainder of the ternary operator will not hide the div.
jQuery(document).ready(function($) {
$.getJSON('https://boards-api.greenhouse.io/v1/boards/forwardnetworks/departments', postings => {
$("#div_block-420-61456").html(`
<div id="job-list">${postings.departments[0].jobs.length == 0 ? $("#job-list").hide() : $("#job-list").show()}<h3 class="dept">${postings.departments[0].name}</h3>
${postings.departments[0].jobs.map(item => `<h4 class="job-title">${item.title}</h4>
<p class="job-descrip">${item.location.name}`).join('')}</div> `);
});
});
I generally get a return of [object object]

As I mentioned in the comments, I would add a guard within the .getJSON success handler that will return early if there are no jobs to display.
The resulting function would be:
const departmentIndex = 0;
$(function ($) {
$.getJSON('https://boards-api.greenhouse.io/v1/boards/forwardnetworks/departments', postings => {
if (postings.departments[departmentIndex].jobs.length === 0) { return; }
$("#div_block-420-61456").html(`
<div id="job-list">
<h3 class="dept">${postings.departments[departmentIndex].name}</h3>
${postings.departments[departmentIndex].jobs.map(item => `
<a href="${item.absolute_url}">
<h4 class="job-title">${item.title}</h4>
</a>
<p class="job-descrip">${item.location.name}`
).join('')}
</div>
`);
});
});
Note: I put the index in a variable so that I could easily test with different departments.
Here is an example fiddle.

Related

how to get count of child elements using selenium web-driver for nodejs

I have searched at numerous places but I am not getting an answer
here is my html :
<form id="search_form_homepage" >
...
<div class="search__autocomplete" style="display: block;">
<div class="acp-wrap js-acp-wrap">
<div class="acp" data-index="0"><span class="t-normal">elephant</span>cheap auto</div>
<div class="acp" data-index="1"><span class="t-normal">elephant</span>asia</div>
...
...
<div class="acp" data-index="2"><span class="t-normal">elephant</span>africa</div>
</div>
...
</div>
</form>
I simply need to get the count of the <div> present within the div with class acp-wrap js-acp-wrap
I can reach this point but am stuck beyond :
let xyz = driver.findElements(By.className(".acp-wrap js-acp-wrap>div"));
You would need to use By.css to get element by this: .acp-wrap js-acp-wrap > div. Also, your selector is not correct. When you select an element by class, you need to put a period before the class name: .acp-wrap.js-acp-wrap > div (remove the space between acp-wrap and js-acp-wrap, too).
Here is how you can get that element now:
let xyz = driver.findElements(By.css(".acp-wrap.js-acp-wrap > div"));
Now to get the count, you can get the length property of xyz. But since driver.findElement returns a promise, you need to use async-await. You can create a function:
async function getCount() {
let xyz = await driver.findElements(By.css(".acp-wrap.js-acp-wrap > div"));
const count = xyz.length;
return count;
}
EDIT
When you call the function:
getCount().then(function(count) {
// your stuff there
});

Cypress: lenght of an invisble array

I know this will be a long questing and I do apologize for it.
TL:TR I'm starting to learn Cypress and I stumbled upon a problem. I got a list which is higly dinamic (meaning that it can and it will have zero elements from time to time) and I want know its length to make some assertions. The thing is that when it has zero elements, Cypress is falling to get this DOM element.
I have no idea how to assert if the array is empty before trying to .get() it. Any clue on how to do it? Thank you in advance!
The post
I want to follow this logic To check if an item was added to the list:
Get array length, save it into a variable. (Need to learn how to)
Add an item (this hasn't been of any problem)
Get new array length, compare it. If new == old + 1, then it was added.
HTML5 (This code HAS an item into the list)
<section id="main" style="display: block;">
<input id="toggle-all" type="checkbox">
<label for="toggle-all">Mark all as complete</label>
<ul id="todo-list">
<li>
<div class="view">
<input class="toggle" type="checkbox">
<label>a</label>
<button class="destroy"></button>
</div>
<input class="edit" value="a">
</li>
</ul>
</section>
HTML5 (This code HAS NOT an item into the list)
<section id="main" style="display: none;">
<input id="toggle-all" type="checkbox">
<label for="toggle-all">Mark all as complete</label>
<ul id="todo-list"></ul>
</section>
Cypress
cy.get('#todo-list').find('.view').each(($el, i) =>
{
cont = i + 1;
cy.log(cont);
})
This approach is clearly not working for many reasons. First of all if the list has zero elements, Cypress does not find it and I cannot proceed. And if it does, later on into the '>' statement my var cont is 0.
I'm sure I'm messing something up.
This is the app, so you can see the html and I can keep this post as short as I can:
Todo List
I've been also trying another approach with the footer > todo-count element and it's working while the list has an element into it. My problem is again when I doesn't:
cy.get('#todo-count').then(($el1) =>{
const prev = parseFloat($el1.text())
cy.log(prev)
{Here I add the item}
cy.get('#todo-count').invoke('text').then(parseFloat).should('be.gt', prev)
})
Again, if the element is not visible Cypress will not find it. Tried if/else with $el.css('display') == 'block' and .is(":visible") but I'm not getting it.
I don't know what's happened to the footer and the #id-count, but don't use it. Count the elements yourself
it('adds an item to the list', () => {
cy.get('ul').then($list => {
const initialCount = $list.find('li').length;
expect(initialCount).to.eq(0)
{Here add the item}
// const afterAddingCount = $list.find('li').length;
// expect(afterAddingCount).to.eq(1);
// This is better
cy.get('ul li')
.should('have.length', 1); // retry on this if animation, etc
})
})
it('updates the todo-count display', () => {
// show the HTML for the footer
// before and after adding an item
// then can add a test here
})
This is how I think you should test the list counter
it('updates the todo-count display', () => {
cy.get('#footer')
.should('have.css', 'display', 'none')
cy.get('#todo-count')
.should('not.exist') // verify counter is not present
// {Here add the item}
cy.get('#footer')
.should('have.css', 'display', 'block')
cy.get('#todo-count')
.should('exist') // now the counter exists
.invoke('text')
.should('include', '1') // and its value is '1'
})

Add a javascript result to an image url

So what im trying to do is query a Minecraft server with javascript, and with the response i get back with the api, i want to grab the .playerlist and put the response in this url (https://cravatar.eu/avatar/ {name} /100.png) for each person connected
If someone knows a better way to achieve this, i would very much appreciate your input!
Im also pretty new to javascript, so not fully know what im doing :/
Heres the HTML that i have (i know it may be messy, its also not fully my code)
<div class="card"> <div class="icon"><img src="https://cdn.worldvectorlogo.com/logos/minecraft-1.svg"></div><div class="header">
<div class="image"> <img src="https://res.cloudinary.com/lmn/image/upload/e_sharpen:100/f_auto,fl_lossy,q_auto/v1/gameskinnyc/u/n/t/untitled-a5150.jpg" alt="" /> </div>
<h2>Server Status</h2>
</div>
<div id="rest">Loading...</div>
<img src="https://cravatar.eu/avatar/" $face "/>
</div>
And here is the javascript
//Query api at this address
var url = "https://api.minetools.eu/query/play.aydaacraft.online/25565";
$.getJSON(url, function(r) {
//data is the JSON string
if(r.error){
$('#rest').html('Server Offline.');
return false;
}
var p1 = '';
if(r.Players > 0 ){ p1 = '<br>'+r.Playerlist; }
// Text to display below
$('#rest').html('Total Online: '+r.Players+p1);
// Trying to add playerlist to html url
$('#face').html+p1;
});
Since you've pasted jQuery code, I'll submit my answer in jQuery. However, I do recommend you learn primitive JavaScript and not focus your attention just on jQuery... it's become something of a meme on StackOverflow.
Starting off, you really should be wrapping your code in $(document).ready this'll only run the code when the page has loaded.
$(document).ready(() => {
// The document is ready, let's run some code!
});
Then add your AJAX request as normal inside this bracket.
$(document).ready(() => {
let url = "https://api.minetools.eu/query/play.aydaacraft.online/25565";
$.getJSON(url, response => {
});
});
Okay, whilst writing this, I checked the URL provided by OP and saw that it was timing out so I've grabbed a sample response from the Minetools' documentation.
{
"MaxPlayers": 200,
"Motd": "A Minecraft Server",
"Playerlist": [
"Connor",
"Kamil",
"David"
],
"Players": 3,
"Plugins": [],
"Software": "CraftBukkit on Bukkit 1.8.8-R0.2-SNAPSHOT",
"Version": "1.8.8",
"status": "OK"
}
So in your JSON response, you can see that Playerlist is a array which can contain multiple things in one variable. You can also iterate through an array, which is what we'll be doing to build the image URLs.
We iterate through an array using forEach.
$(document).ready(() => {
let url = "https://api.minetools.eu/query/play.aydaacraft.online/25565";
$.getJSON(url, response => {
response.Playerlist.forEach(playerName => {
console.log(playerName);
});
});
});
//Console:
//Connor
//Kamil
//David
Now that we're iterating through the player list we can start assembling the URLs for these images and adding them to your document's body.
I've cleaned up your HTML, take note of the new div#user-images I've added. This'll be the place where jQuery will add your images from the forEach loop.
<div class="card">
<div class="icon">
<img src="https://cdn.worldvectorlogo.com/logos/minecraft-1.svg">
</div>
<div class="header">
<div class="image">
<img src="https://res.cloudinary.com/lmn/image/upload/e_sharpen:100/f_auto,fl_lossy,q_auto/v1/gameskinnyc/u/n/t/untitled-a5150.jpg" alt="" />
</div>
<h2>Server Status</h2>
</div>
<!-- This div tag will need to hide when there is no error, or say when there is. -->
<div id="rest">Loading...</div>
<!-- The user images will be added inside this div. -->
<div id="user-images"></div>
</div>
Now we have our HTML ready we can start using the jQuery function appendTo to add elements into our div#user-images.
$(document).ready(() => {
let url = "https://api.minetools.eu/query/play.aydaacraft.online/25565";
$.getJSON(url, response => {
response.Playerlist.forEach(playerName => {
$(`<img src="https://cravatar.eu/avatar/${playerName}" />`).appendTo("#user-images");
});
});
});
Your div#user-images should start filling up with the images of players from the Playerlist array.
I noticed you added a simple way of showing whether or not there's an error with the API. We can interact with div#rest to show/hide or change text depending on the success of the response.
$(document).ready(() => {
let url = "https://api.minetools.eu/query/play.aydaacraft.online/25565";
$.getJSON(url, response => {
if(response.error){
$("#rest").html("The server is offline!");
}else{
//There is no error, hide the div#rest
$("#rest").hide();
response.Playerlist.forEach(playerName => {
$(`<img src="https://cravatar.eu/avatar/${playerName}" />`).appendTo("#user-images");
});
}
});
});
And that's it really. I hope this gives you some understanding of arrays, and iterating through them, as well as some DOM functions from jQuery.

Protractor: How to correcly set an expectation getText() of each function?

I’m testing a page with filtered products by title, and want to set an expectation about the correctness of the test: that all titles on the page consist a WORD «Juvederm», NOT any other titles («Emla», «Coolsense» etc.)).
And should ONLY find the title by the first word - Juvederm (not the Full title: JUVEDERM® ULTRA SMILE Europe; JUVEDERM® VOLBELLA WITH LIDOCAINE Europe).
Html of one product is:
<div class="col-xs-12 col-sm-6 col-md-4 block_history_" style="">
<section class="product">
<div class="product__holder">
<h2 class="product__title">
JUVEDERM® HYDRATE™ Europe
</h2>
</div>
</section>
My code console.log(s) correctly (if "Juvederm" is available on the page - it shows "Passed", if not - "NOT PASSED":
it("products titles on the page should be Juvederm", () => {
let product = $$(".product > div > h2 > a");
browser.get(«…/advanced_search.html?keyword=juvederm");
product.each(function(element, index) {
element.getText().then(function(text) {
if(text.indexOf("JUVEDERM®") !== -1) {
console.log(«Passed»);
}else{
console.log("NOT PASSED");
}
});
});
});
But I decided for myself that I need to have an expectation.
How/Where to set it? And what expectation must be? When I use in "If"
expect(order.product.getText()).toEqual(text);
I get an error about differences of texts:
JUVEDERM® HYDRATE™ Europe toEqual JUVEDERM®
When I used in "If"
browser.wait(() => {
return EC.textToBePresentInElement(order.product);
}, 3000, "ASDF");
test Passed (but I need to see "JUVEDERM®", not "ASDF").
Please, advice smth.
You need to change expect statement like below.
expect(order.product.getText()).toContain('JUVEDERM®');
Use toContain() to check including substring or not.
it("products titles on the page should be Juvederm", () => {
let products = $$(".product .product__title > a");
browser.get("advanced_search.html?keyword=juvederm");
products.each(product => {
expect(product.getText()).toContain('JUVEDERM®');
});
});

Array is returning correct results. but shows undefined in HTML display

I am having an issue with a project I'm working on. I am using an API to return an array of platforms a video game is on. The array is returning the correct results, however I am having trouble displaying those values in my HTML. The result is just showing undefined.
// Renders platform information for each game
const renderPlatformInfo = function (platformResult) {
const gamePlatform = [];
for (let i = 0; i <= `${platformResult.length - 1}`; i++) {
let getPlatforms = gamePlatform.push(platformResult[i].name);
}
gamePlatform.forEach(function (platformItem) {
$('.platforms').append(`<li>${platformItem}</li>`)
});
console.log(gamePlatform);
};
// Renders game information for the searched game
const renderGameInfo = function (gameInfoResult) {
return `<div class="js-game-data row">
<h2 class="game-name col-12">${gameInfoResult.name}</h2>
<img src="${gameInfoResult.image.medium_url}" class="game-image col-4" alt="Box art for ${gameInfoResult.name}">
<ul class="platforms col-6">
<h3 class="col-12">Original release date:</h3>${gameInfoResult.original_release_date}
<h3>Platforms:</h3>
${renderPlatformInfo(gameInfoResult.platforms)}
</ul>
<p class="game-description col-6">${gameInfoResult.deck} <br> <br> <span class="game-details col-12"><b>For more details about the game: Click Here</b></span></p>
</div>
`;
}
renderPlatformInfo can't append children to a DOM element that doesn't exist yet. The UL it's trying to select isn't rendered at the time you're trying to append. Additionally, since renderPlatformInfo doesn't return anything, it will always evaluate to undefined inside a template literal. If you return an HTML string inside renderPlatformInfo, your code should work. Try something like:
let str = '';
gamePlatform.forEach(function(platformItem){
str += `<li>${platformItem}</li>`;
});
return str;
Should renderPlatformInfo return something. Are you missing the return there?

Categories

Resources