Playwright Test Library: How to verify whether two nodes are equal - playwright

I am trying to traverse from child element to parent element and verify whether the child and parent nodes are equal. I had used evaluate function which is throwing some exception.
I am not able to find the exact syntax. Below is the code.
console.log("Parent Element "+ parent);
let c1 = await page.locator(`${childEle} ${parent}`, {hasText: txt}).first().evaluate(node => node);
console.log("c1 "+ c1);
let p1 = await page.locator(parentEle).first().evaluate(node => node);
await page.evaluate(
([c1, p1]) => p1.isEqualNode(c1),
[c1, p1]);
output is:
Basically, it clicks on the element which matches the text within the element. Clicking the element with the text with the top-down and bottom-up approach.

I got the solution to verify two nodes are equal. Below is the code
console.log("Parent Element "+ parent);
let c1 = await page.locator(`${childEle} ${parent}`).first().evaluateHandle(node => node);
let p1 = await page.locator(parentEle).first().evaluateHandle(node => node);
const inpuValue = await page.evaluateHandle(
([c1, p1]) => c1.parentNode.isEqualNode(p1.parentNode),
[c1, p1]);
console.log("inputValue "+ inpuValue);
I have used evaluateHandle instead of evaluate function.

Related

Retrieve an element of a list that satisfy a condition

This is my model class:
class Contact {
String name;
String email;
int phoneNo;
Contact(this.name, this.email, this.phoneNo);
}
Suppose I have a list of contacts like below:
List<Contact> contacts = [
new Contact('John', 'john#c.com', 002100),
new Contact('Lily', 'lily#c.com', 083924),
new Contact('Abby', 'abby#c.com', 103385),
];
I want to get John's phone number from contacts List, how can I do that?
singleWhere throws if there are duplicates or no element that matches.
An alternative is firstWhere with orElse https://api.dartlang.org/stable/1.24.3/dart-core/Iterable/firstWhere.html
var urgentCont = contacts.firstWhere((e) => e.name == 'John', orElse: () => null);
print(urgentCont?.phoneNo?.toString()?.padLeft(6, '0') ?? '(not found)');//Output: 002100
This is how I do it using singleWhere:
var urgentCont = contacts.singleWhere((e) => e.name == 'John');
print(urgentCont.phoneNo.toString().padLeft(6, '0'));//Output: 002100
singleWhere(bool test(E element)) → E Returns the single element that
satisfies test.
And there is some other methods in List class. As a example where():
where(bool test(E element)) → Iterable<E> Returns a new lazy Iterable
with all elements that satisfy the predicate test.
Update:
singleWhere() throws an error when there is no matching elements(Bad state: No element). And if there are duplicates, will throw Bad state: Too many elements
So, the best one is firstWhere according to #GunterZochbauer(refer his answer)

How can we copy labels from one node to another in one cypher?

The question is just as the title, and the cypher statement is just like the follow:
Match (n: test) CREATE (copy : LABELS(n)) set copy = n
Its purpose is to create a node with the same properties and same labels as the other node, but it doesn't work now because we cannot use a expression like LABELS(n) to set lobel to a node.
How can I make it work?
Unfortunately, labels currently cannot be set directly from data values.
You could get the node's properties and labels you want to copy and then dynamically create another cypher statement that you execute.
Using the transactional api, it could look like this:
// requires cypher-rest
// npm i cypher-rest
'use strict';
const util = require('util');
const c = require('cypher-rest');
const neoUrl = 'http://127.0.0.1:7474/db/data/transaction/commit';
const copyNode = propertyObjMatch => {
return new Promise((resolve, reject) => {
// find node(s) via property matching and return it(/them)
const cypher = `MATCH (x ${util.inspect(propertyObjMatch)}) RETURN DISTINCT x, LABELS(x) AS labels`;
return c.run(cypher, neoUrl, true) // third parameter set to true to always return a list of results
.then(results => {
// iterate over results and create a copy one by one
results.forEach(result => {
const copy = `CREATE (copy:${[...result.labels].join(':')}) SET copy = ${util.inspect(result.x)} RETURN copy`;
c.run(copy, neoUrl);
});
})
});
};
// create a node
c.run('CREATE (x:LABEL1:LABEL2 {withProp: "and value", anotherProp: "test"}) RETURN x', neoUrl).then(() => {
copyNode({withProp: 'and value', anotherProp: 'test'})
.then(console.log)
});
Please excuse the hackiness, but it should bring the point across.

Adding to SortedLinkedList using nodes

im making a SortedLinkedList, I'm trying to add lets say 10 integers of different value so I can run some asssert tests. But I'm having a problem adding them so they are already sorted when they arrive to the LinkedList, I tried using the curr.info.compareTo(x) > 0 for instance, but I'm having trouble making the correct else/if statements so it sorts them when they are added.
This code has 4 classes, I can provide more if its unclear.
Thank you for your help in advance.
Best regards,
Victor
public class SortedLinkedList<T extends Comparable<T>> implements Iterable<T> {
/* Easy operations for a linked list
add(x): Searching for the place where the element x is to be added must
take place in the calling routine. This must set previous to
point to the node AFTER which the new element is to be inserted.
curr is set to point to the new element.
remove(): The curr element is removed from the list. Searching for this
element must take place in the calling routine. This must set
curr to point to the element to be removed. After removal curr
points to the element following the removed one.
isEmpty(): checks for an empty list
endOfList(): checks whether curr has reached and passed the end of the list
retrievecurr(): return the info part of the curr element.
reset(): resets the list so that curr points to the first element
succ(): an iterator, moves curr one step forward
Note that when a class implements the interface Iterable<T> then
it can be the target of the "foreach" statement. See IterationExample.java */
private Node start, curr, prev;
public SortedLinkedList() {
curr = null; // the curr position in the list
start = null; // the first element
prev = null; // the node before curr
}
public void add(T x) {
if (start == null) { // if start == null, insert a first element into an empty list
Node newNode = new Node(); // create the new element, info and link are set to null.
newNode.info = x; // and assign the data given as parameter. The link is left as null
start = newNode; // start is updated to point to the new element
curr = start; // curr is updated to point to the new first (and only) element
} else if (prev == null) { // a new first element is inserterd into a non-empty list
Node newNode = new Node(); // a new node is created ...
newNode.info = x; // and assigned the data given as parameter
newNode.link = start; // and linked before the old first element
start = newNode; // start is updated to point to the new first element
curr = newNode; // curr is updated to point to the new first element
} else { // a new element is inserted last (if prev.link == null) or between prev and curr
Node newNode = new Node(); // create a new node
newNode.info = x; // assign it the data given as parameter
newNode.link = prev.link; // link it before curr ...
prev.link = newNode; // ... and after previous
curr = newNode; // update curr to point to newNode
}
} // add*
}

Neo4j Cypher: String Build with Unwind and Array

Im using an unwind query in neo4j, with a nodejs driver (https://github.com/philippkueng/node-neo4j)
What I am trying to do is include an array of objects in the unwind query.
It currently works if I hard code the string as shown below, but i'm trying to have the array inserted dynamically.
UNWIND [{Label:'User',Lang:'English'},{Label:'Usuario',Lang:'Español'},{Label:'用户',Lang:'中文_简体'}] as ll
Regardless of the query I use, after testing, the above works, but if I do something like the following it doesn't:
var MyList = [{Label:'User',Lang:'English'},{Label:'Usuario',Lang:'Español'},{Label:'用户',Lang:'中文_简体'}];
"UNWIND "+ MyList " + as ll"
The problem is that when you do "UNWIND " + MyList you convert MyList to string, and it will be something like [object Object],[object Object],.... My first idea was to use JSON.stringify but that produces a JSON, which is not ok in cypher syntax (it is { "Label": ... } instead of { Label: ... }). The solution is to use parameters:
var queryString = 'UNWIND {list} as ll // continue query';
var queryParams = { list: MyList };
db.cypherQuery(queryString, queryParams, function(err, res) {
// handle response
});
Ideally you would use the ll identifier in your query.
However by seeing you have a property named Label, I remind you that currently it is not possible to add labels dynamically.
A possible query you might do is :
UNWIND MyList AS ll
CREATE (user:User) SET user.lang = {ll}.Lang
Chris

How do I extract results individually from an ExecutionResult?

I have the following java code snippet that demonstrates the problem. The error I receive is also included below.
It correctly pulls the correct set, but I am having trouble printing.
I'm using the org.neo4j.graphdb.Node node. Is this the wrong class?
If not, how do I obtain the results movieid, avgrating and movie_title from the ExecutionEngine?
Java Code
GraphDatabaseService db = new GraphDatabaseFactory().newEmbeddedDatabase(DB_PATH);
ExecutionEngine engine = new ExecutionEngine(db);
String cypherQuery = "MATCH (n)-[r:RATES]->(m) \n"
+ "RETURN m.movieid as movieid, avg(toFloat(r.rating)) as avgrating, m.title as movie_title \n"
+ "ORDER BY avgrating DESC \n"
+ "LIMIT 20;";
ExecutionResult result = engine.execute(cypher);
for (Map<String, Object> row : result) {
Node x = (Node) row.get("movie_title");
for (String prop : x.getPropertyKeys()) {
System.out.println(prop + ": " + x.getProperty(prop));
}
}
Error
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to org.neo4j.graphdb.Node
at beans.RecommendationBean.queryMoviesWithCypher(RecommendationBean.java:194)
at beans.RecommendationBean.main(RecommendationBean.java:56)
Node x = (Node) row.get("movie_title");
...looks to be the culprit.
In your Cypher statement, you return m.title as movie_title, i.e. you're returning a node property (in this case, a string), and, in the offending line, you're trying to cast that string result as a Node.
If you want Cypher to return a series of nodes you can iterate through, try returning m (the whole node) instead of just individual properties and aggregates, e.g.
"...RETURN m AS movie;"
...
Node x = (Node) row.get("movie");
Etc.

Resources