Svelte {# if } block length is not possible. How to get the length of the if block - sapper

I have a page with products/items. Some with options that the user needs to choose and some with no options at all.
In my shopping cart page, I display this ordered items/products with the options user chose if needed. This is how I iterate over products/item and the options
{#each eachitem as item }
<li>
Here it is : {item.item.id} -- {item.price} -- {item.qty}
{#if item.item.checkedoptions.checkoptions === 0 }
<p> Display NO OPTIONS</p>
{:else}
{#each item.item.checkedoptions.checkoptions[1] as opti}
<li style="list-style-type : none">
Options : {opti.optionname} - {opti.optionvalue}
</li>
{/each}
{/if}
</li>
{/each}
The issue is when there are no options, I get the error in my dev tools that reads "Cannot read property 'length' of undefined", of course because item.item.checkedoptions.checkoptions[1] is empty. I tried to use length but couldn't figure out how to attach it to item.item.checkedoptions.checkoptions do I put it inside () or [] or what?
How do you write if statement that if item.... length === 0 {do something}?
If I can't get the length, how do I solve this problem, do I do something in the script before I iterate?
How do you solve this issue?

In your if statement you are not actually checking the length of checkoptions you are comparing it directly with 0
You should change this to #if item.item.checkedoptons.checkoptions.length === 0

Related

How to select by non-direct child condition in Xpath?

I would like to show an example.
This how the page looks:
<a class="aclass">
<div class="divclass"></div>
<div id="innerclass">
<span class="spanclass">Hello</span>
</div>
</a>
<a class="aclass">
<div class="divclass"></div>
<div id="innerclass">
<span class="spanclass">Pick Delivery Location</span>
</div>
</a>
I want to select anchor tags that have a child (direct or non-direct) span that has the text 'Hello'.
Right now, I do something like this:
//a[#class='aclass'][div/span[text() = 'Hello']]
I want to be able to select without having to select direct children (div in this case), like this:
//a[#class='aclass'][//span[text() = 'Hello']]
However, the second one finds all the anchor tags with the class 'aclass' rather than the one with the span with 'Hello' text.
I hope I worded my question clearly. Please feel free to edit if necessary.
In your attempt, // goes back to the root of the document - effectively you are saying "Give me the as for which there is a span anywhere in the document", which is why you get them all.
What you need is the descendant axis :
//a[#class='aclass' and descendant::span[text() = 'Hello']]
Note I have joined the conditions with and, but two separate conditions would also work.

Using XPath to get complete text of paragraph with span inside

<ul>
<li class="xyz">
<div class="divClass">
<span class="ContentItem---status---dL0iS">
<span>Success</span>
</span>
<p class="ContentItem---title---37IqA">
<span>Test Check</span>
: Please display the text
</p>
</div>
</li>
<li class="xyz">
<div class="divClass">
<span class="ContentItem---status---dL0iS">
<span>Not COMPLETED</span>
</span>
<p class="ContentItem---title---37IqA">
<span>Knowledge</span> A Team
</p>
</div>
</li>
.... and so on
</ul>
This is my html structure.I have this text Test Check inside a Span and : Please display the text inside a Paragraph tag.
What i need is ,i need to identify, whether my structure contains this complete text or not Test Check: Please display the text.
I have tried multiple ways and couldn't identify the complete path.Please find the way which i have tried
//span[text()='Test Check']/p[text()=': Please display the text']
Can you please provide me the xpath for this?
I think there is one possible solution to identify within the given html text and retrieve. I hope this solves your problem.
def get_tag_if_present(html_text):
soup_obj = BeautifulSoup(html_text,"html.parser")
test_check = soup_obj.find_all(text = re.compile(r"Test Check"))
result_val = "NOT FOUND"
if test_check:
for each_value in test_check:
parent_tag_span = each_value.parent
if parent_tag_span.name == "span":
parent_p_tag = parent_tag_span.parent
if parent_p_tag.name == "p" and "Please display the text" in parent_p_tag.get_text():
result_val = parent_p_tag
break
return result_val
The returned result_val will have the tag corresponding to the p tag element with the parameter. It would return NOT FOUND, if no such element exists.
I've taken this with the assumption that the corresponding data entries would exist in a "p" tag and "span" tag respectively , feel free to remove the said conditions for all identifications of the text in the given html text.

XPath in RSelenium for indexing list of values

Here is an example of html:
<li class="index i1"
<ol id="rem">
<div class="bare">
<h3>
<a class="tlt mhead" href="https://www.myexample.com">
<li class="index i2"
<ol id="rem">
<div class="bare">
<h3>
<a class="tlt mhead" href="https://www.myexample2.com">
I would like to take the value of every href in a element. What makes the list is the class in the first li in which class' name change i1, i2.
So I have a counter and change it when I go to take the value.
i <- 1
stablestr <- "index "
myVal <- paste(stablestr , i, sep="")
so even if try just to access the general lib with myVal index using this
profile<-remDr$findElement(using = 'xpath', "//*/input[#li = myVal]")
profile$highlightElement()
or the href using this
profile<-remDr$findElement(using = 'xpath', "/li[#class=myVal]/ol[#id='rem']/div[#id='bare']/h3/a[#class='tlt']")
profile$highlightElement()
Is there anything wrong with xpath?
Your HTML structure is invalid. Your <li> tags are not closed properly, and it seems you are confusing <ol> with <li>. But for the sake of the question, I assume the structure is as you write, with properly closed <li> tags.
Then, constructing myVal is not right. It will yield "index 1" while you want "index i1". Use "index i" for stablestr.
Now for the XPath:
//*/input[#li = myVal]
This is obviously wrong since there is no input in your XML. Also, you didn't prefix the variable with $. And finally, the * seems to be unnecessary. Try this:
//li[#class = $myVal]
In your second XPath, there are also some errors:
/li[#class=myVal]/ol[#id='rem']/div[#id='bare']/h3/a[#class='tlt']
^ ^ ^
missing $ should be #class is actually 'tlt mhead'
The first two issues are easy to fix. The third one is not. You could use contains(#class, 'tlt'), but that would also match if the class is, e.g., tltt, which is probably not what you want. Anyway, it might suffice for your use-case. Fixed XPath:
/li[#class=$myVal]/ol[#id='rem']/div[#class='bare']/h3/a[contains(#class, 'tlt')]

Can nightwatchjs perform an assertion based on a reference with accuracy?

In a case where a same element could change for a different id or name depending on many factors, I would be able to do an assertion on this element with accuracy.
Doest nighwatchjs permit to do an assertion based on a relative position like can do SAHI ? (Left of this element ..., Under a div, etc.)
I want to avoid Xpath solutions, it's based on the element type (div, id, name, etc.) and if I set it to all types:
//*[contains(text(),'hello world')]
I will get many occurrences and couldn't be able to know which one I'm trying to assert.
e.g : Running the same test on the same page, I would be able to find this "hello world" even if the div id changes or another element.
<div id="homebutton">
<p>
<a href=#>
<span name="hm">Home</span>
<a>
</p>
</div>
<div id=[0-9]>
<p>
<a href=#>
<span name="hw">hello world</span>
<a>
</p>
</div>
[...]
<div id=[0-9]>
<p>
<a href=#>
<span name="hw">hello world</span>
<a>
</p>
</div>
<div id="logoutbutton">
<p>
<a href=#>
<span name="lo">Logout</span>
<a>
</p>
</div>
Test example : Assert element containing string "hello world", not the one which is near the logout button but the one which is near the home button.
Expanding on my previous answer, you have two options, if the Hello World you want is *always the 2nd to last, appearing just before the Logout button then you want the 2nd to last of a type, you could use an xPath selector like this:
"//*[.='hello world'][last()-1]"
That's right in the Rosetta doc I shared with you, so you should know that by now
Another option is to get a collection of all matches. For that, I'd write a helper function like so:
module.exports = {
getCountOfElementsUseXpath : function (client, selector, value) {
// set an empty variable to store the count of elements
var elementCount;
// get a collection of all elements that match the passed selector
client.getEls(selector, function(collection) {
// set the variable to be that collection's length
elementCount = collection.length;
// log the count of elements to the terminal
console.log("There were " + elementCount + " question types")
return elementCount;
});
},
};
Then you can use that with some formula for how far your selector is from the last element.
The xpath selector "//div[contains(text(), 'hello world')]"
would match on both of the elements you've shown. If the element itself can change, you would use a wildcard: "//*[contains(text(), 'hello world')]"
For a match, on any element with that exact text:
"//*[.='hello world']"
A great source, a "Rosetta stone", for selector construction
To use an xpath selector with nightwatch:
"some test": function(client){
client
.useXpath().waitForElementPresent("//div[contains(text(), 'hello world')]", this.timeout)
}
The Xpath solution is okay but here is the solution I needed, more generic and giving many more options :
Using elements and manage to return an array of childrend elements
I choosed to return an array of objects with data matching my needs :
[{ id: webElementId, size: {width: 18, height: 35}, ...}, {id: webElementId, ...}, etc.]
With those informations, I can do many things:
Find an element with a specific text, attribute or cssproperty and
perform any action on it, like assertions or click on the right of it through a calculation of his size.
Mouse hover each elements matched (if you want to browse tabs with
submenus ul li / ol li)
More data is filled, more you can perform assertions.

Begin ordered list from 0 in Markdown

I'm new to Markdown. I was writing something like:
# Table of Contents
0. Item 0
1. Item 1
2. Item 2
But that generates a list that starts with 1, effectively rendering something like:
# Table of Contents
1. Item 0
2. Item 1
3. Item 2
I want to start the list from zero. Is there an easy way to do that?
If not, I could simply rename all of my indices, but this is annoying when there are several items. Beginning a list from zero seems so natural to me, it's like beginning the index of an array from zero.
Simply: NO
Longer: YES, BUT
When you create ordered list in Markdown it is parsed to HTML ordered list, i.e.:
# Table of Contents
0. Item 0
1. Item 1
2. Item 2
Will create:
<h1>Table of Contents</h1>
<ol>
<li>Item 0</li>
<li>Item 1</li>
<li>Item 2</li>
</ol>
So as you can see, there is no data about starting number. If you want to start at certain number, unfortunately, you have to use pure HTML and write:
<ol start="0">
<li>Item 0</li>
<li>Item 1</li>
<li>Item 2</li>
</ol>
You can use HTML start tag:
<ol start="0">
<li> item 1</li>
<li> item 2</li>
<li> item 3</li>
</ol>
It's currently supported in all browsers: Internet Explorer 5.5+, Firefox 1+, Safari 1.3+, Opera 9.2+, Chrome 2+
Optionally you can use type tab for more sophisticated enumerating:
type="1" - decimal (default style)
type="a" - lower-alpha
type="A" - upper-alpha
type="i" - lower-roman
type="I" - upper-roman
Via html: use <ol start="0">
Via CSS:
ol {
counter-reset: num -1; // reset counter to -1 (any var name is possible)
}
ol li {
list-style-type: none; // remove default numbers
}
ol li:before {
counter-increment: num; // increment counter
content: counter(num) ". ";
}
FIDDLE
Update: Depends on the implementation.
The current version of CommonMark requires the start attribute. Some implementations already support this, e.g. pandoc and markdown-it. For more details see babelmark.

Resources