selector in react-testing-library that can retrieve a number of matches by getAllByText - react-testing-library

At the moment I am doing this to pull back all the rows of a table:
const { getByTestId } = renderWithRouter(businessWithContext);
const firstTableRow = await waitForElement(() => getByTestId("row-1-name"));
const secondTableRow = await waitForElement(() => getByTestId("row-2-name"));
expect(firstTableRow.textContent).toBe("test1");
expect(secondTableRow.textContent).toBe("test2");
I would rather do something like this:
const rows = await waitForElement(() => getAllByText(/^row-*/gi));
But I get this error:
Unable to find an element with the text: /^row-*/gi. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

You are using getAllByText but you really want to query by data-testid. This will work:
getAllByTestId(/^row-*/)

Related

How to Call Dynamic Variable on Flutter

I have the following code
List toCheck = ['province','regency','district','village'];
List data = [];
toCheck.forEach((value) {
//sample data would looke like (object.province)
if(object.value!=null){ => need to call with object.value
data.add(value);
}
});
If it is in php, that would be look like ${$value}
Try this:
ElevatedButton(onPressed: (){
List toCheck = ['province','regency','district','village'];
List data = [];
toCheck.forEach((value) {
//sample data would looke like (object.province)
if(value!=null){
data.add(value);
}
});
If I understand what you want correctly, this should check if the values of your list are not null, and if so, it will add each value to the data list.

Dart / Flutter : Waiting for a loop to be completed before continuing... (Async Await?)

I have a function which creates a sublist from a large(very large list). After creating this list, the function goes on treating it (deleting duplicates, sorting...).
As long as the list was not too big, it worked fine. But now, I get "The Getter length was called on null". I suppose, it's because the second part of the function (after the loop) starts before the sublist is completed... so it doesn't work...
How can we force the function to wait for the loop to be over to continue the rest of the treatment ?
Is it with Async /Await ? Or can we do something like "While... something is not over...", or "As soon as something is done... do that" ? (My suggestions might be naive, but I am a beginner...)
Here is the code :
List themeBankFr() {
List<Map> themeBankFr = [];
for (Word word in wordBank) {
for (Thematique wordTheme in word.theme) {
themeBankFr.add({
'themeFr': wordTheme.themeFr,
'image': wordTheme.image,
});
}
}
// convert each item to a string by using JSON encoding
final jsonList = themeBankFr.map((item) => jsonEncode(item)).toList();
// using toSet - toList strategy
final uniqueJsonList = jsonList.toSet().toList();
// convert each item back to the original form using JSON decoding
final result = uniqueJsonList.map((item) => jsonDecode(item)).toList();
// sort the list of map in alphabetical order
result.sort((m1, m2) {
var r = m1['themeFr'].compareTo(m2['themeFr']);
if (r != 0) return r;
return m1['image'].compareTo(m2['image']);
});
return result;
}
i think i have a good answer that may helps you and it will as following
first create another function to do the work of for loops and this function returns a future of list that you need like below
Future<List<Map>> futureList(List wordBank){
List<Map> themeBankFr = [];
for (Word word in wordBank) {
for (Thematique wordTheme in word.theme) {
themeBankFr.add({
'themeFr': wordTheme.themeFr,
'image': wordTheme.image,
});
}
}
return Future.value(themeBankFr);
}
after that you can use this function inside your code and use it as async await and now you will never run the below lines before you return this array like below
List themeBankFr() async {
List<Map> themeBankFr = await futureList(wordBank);
// convert each item to a string by using JSON encoding
final jsonList = themeBankFr.map((item) => jsonEncode(item)).toList();
// using toSet - toList strategy
final uniqueJsonList = jsonList.toSet().toList();
// convert each item back to the original form using JSON decoding
final result = uniqueJsonList.map((item) => jsonDecode(item)).toList();
// sort the list of map in alphabetical order
result.sort((m1, m2) {
var r = m1['themeFr'].compareTo(m2['themeFr']);
if (r != 0) return r;
return m1['image'].compareTo(m2['image']);
});
return result;
}
i think this will solve your problem and i hope this useful for you

How to have an empty string as a parameter value in Flutter/Dart?

Suppose you want to send an empty search query to an API. For example:
https://api.example.com/search?query=''
In Dart, it makes sense to create this URI with:
final uri = Uri.https('api.example.com', 'search', {'query': ''});
But if you try to print this out: print(uri); you will see:
https://api.example.com/search?query
My current workaround is to wrap double-quotes inside single-quotes (or other way around):
final uri = Uri.https('api.example.com', 'search', {'query': '""'});
which produces this URI:
https://api.example.com/search?query=%22%22
Not a big deal. But still this behavior surprised me as a bit illogical. Who would want to send only a parameter name and not its value? Is it a problem of http library or am I missing something here? Is it the intended behavior and actually serves a purpose?
Was looking for the same use case too. Looked around and ended up with this with some inspiration from the plain javascript implementation.
void main() {
String fullURL = 'http://api.example.com/search';
Object queryParameters = {'query': '', 'colour': 'green', 'name': ''};
String queryString = getQueryString(queryParameters);
fullURL += '?' + queryString;
print(fullURL); // http://api.example.com/search?query=&colour=green&name=
}
getQueryString(object) {
var str = [];
object.forEach(
(k, v) => str.add(Uri.encodeComponent(k) + "=" + Uri.encodeComponent(v)),
);
return str.join("&");
}

How to get the state from redux-saga select()?

the saga like below.
function *callUserAuth(action) {
const selectAllState = (state) => state;
const tmp = yield select(selectAllState);
console.log(tmp);
}
the console show
enter image description here
how can i get state like
getState["userLoginReducer","isLogin"] in redux ?
i had tried to code like below.
const tmp = yield select(selectAllState._root.entries);
but error is
index.js:1 TypeError: Cannot read property 'entries' of undefine
It seems you are using Immutable.js for your redux state.
The select effect doesn't convert your Immtuable structure to plain javascript. So you need to use methods of Immutable to get to the values you want. To get the whole Immutable state and then convert it to plain javascript object you can do:
function *callUserAuth(action) {
const selectAllState = (state) => state;
const tmp = yield select(selectAllState);
console.log(tmp.toJS());
}
But generally you will probably want to have selectors to get a subset like the isLogin value. In that case you can do this instead:
function *callUserAuth(action) {
const getIsLogin = (state) => state.get('userLoginReducer').get('isLogin');
const isLogin = yield select(getIsLogin);
console.log(isLogin);
}

Converting an ElementHandle to a DOM element using puppeteer?

This is how I currently get each DOM property from an ElementHandle :
let section: ElementHandle = await page.waitForSelector(".selector-list li");
let tagName = await section.$eval('a', (e) => e.tagName);
But here it's tagName. What if I'd like want to inspect further properties ?
I don't want to write $eval for each property.
Question:
How can I convert ElementHandle to a Dom object , so I'd be able
to browse all properties ?
I want to get A as a Dom object.
The better way would be to execute the code on the page via page.evaluate and return the results. That way you can return an array with values:
const result = await page.evaluate(() => {
const elements = document.querySelectorAll(".selector-list li");
// do something with elements, like mapping elements to an attribute:
return Array.from(elements).map(element => element.tagName);
});
result will then be an array with the attribute values of tagName of each element.
Use ElementHandle.evaluate():
const elementHandle = await page.waitForSelector('.selector-list li')
elementHandle.evaluate((domElement) => {
domElement.tagName
// etc ...
})
Typescript:
const elementHandle: ElementHandle = await page.waitForSelector('.selector-list li')
elementHandle.evaluate((domElement) => {
domElement.tagName
// etc ...
})