Playwright Comboboxes - combobox

How do I loop through all the options in a combobox using Playwright?
There is no list of options and the values are dynamically generated and at the moment this is what codegen has given me to firstly open the dropdown and then select one of the options:
await page.getByRole('button', { name: 'Open' }).first().click();
await page.getByRole('option', { name: 'Option Value 1' }).click();
Codegen only gives me the different options available in the combobox dropdown by name but I need to dynamically step through each option and select it.

I would probably do that by getting all inner texts of the combo and then enumerate over that, see below:
const combo = await page.getByRole('button', { name: 'Open' });
const comboOptions = combo.locator(`option`);
const comboOptions = await comboOptions.allInnerTexts();
const optionsCount = comboOptions.length;
for (let i = 0; i < optionsCount; i++) {
await combo.selectOption({ label: comboOptions[i] });
}
Please upvote and mark as answered if this helps :)

Related

how to collapse objects in storybook controls

I searched through storybook's documentation for react and I can't seem to find how to make the object control for my argument appear collapsed by default instead of having to collapse it manually.
this is what I did
data: {
control: { type: 'object' },
table: { defaultValue: { summary: 'Object' } },
collapsed: true, // I want to find out if there is something like this
},
and this is what I was expecting
The option to configure this does not exist, unfortunately. Inspired by this comment regarding having the RAW-view open by default, I made a somewhat hacky solution, query all the spans at the top level for collapsing their content and trigger a click using JavaScript.
In the file manager.js add the following to make this work:
const observer = new MutationObserver(() => {
// Query the spans for collapsing objects.
const objectCollapseSpans = [...document.querySelectorAll('.rejt-tree > .rejt-object-node > span')];
// Query the spans for collapsing array of objects.
const arrayCollapseSpans = [...document.querySelectorAll('.rejt-tree > .rejt-array-node > span')];
const collapseSpans = [...arrayCollapseSpans, ...objectCollapseSpans];
for (const span of collapseSpans) {
if (span.className !== 'closed') {
span.click();
}
span.className = 'closed'
}
});
observer.observe(document.body, {
childList: true,
subtree: true,
})

How to test if a button is conditionally enabled in React Testing Library / Jest

I need to test if a button is conditionally enabled after text inputs are filled out.
Right now simply checking to see if they are disabled works with the following:
expect(screen.getByTestId('select-service-btn').closest('button')).toBeDisabled();
But I want to check if they get enabled after input values are filled out.
This is what I currently have.
it('Should test to see if a button gets enabled when forms are filled out', () => {
const firstInput = screen.getByTestId('firstName-input');
const lastInput = screen.getByTestId('lastName-input');
const emailInput = screen.getByTestId('email-input');
expect(screen.getByTestId('select-service-btn').closest('button')).toBeDisabled();
fireEvent.change(firstInput, {
target: { value: 'test content' },
});
fireEvent.change(lastInput, {
target: { value: 'test content' },
});
fireEvent.change(emailInput, {
target: { value: 'test content' },
});
expect(screen.getByTestId('select-service-btn').closest('button')).not.toBeDisabled();
})
I want to say this would check to see if a button is disabled, mimic filling out the necessary inputs, and then check to see if the button changed from disabled to enabled. But the test fails.

Search for a particular field in a array object and put it in another array for displaying a table in angular

I am new to angular I am getting an object array as a response from the server I need to search if any of the arrays have same key value and then put the corresponding array element values in another array for displaying it in a table.
My scenario I am passing Inquiry Number as my input Eg: 10002
My Inquiry response contains the following details Inquirydocumentno, inquirydate, materialno, name of materialinquired etc..,
My actual Response is
[
{
InquiryDate: ["2015-03-04"]
InquiryType:["A"]
MaterialNo: ["30"]
Material Name: ["Chair"]
InquiryDocument No: ["0010000012"]
},
{
InquiryDate: ["2019-03-04"]
InquiryType:["A"]
MaterialNo: ["31"]
Material Name: ["Book"]
InquiryDocument No: ["0010000015"]
},
{
InquiryDate: ["2019-03-04"]
InquiryType:["A"]
MaterialNo: ["31"]
Material Name: ["Bag"]
InquiryDocument No: ["0010000015"]
},
{
InquiryDate: ["2015-05-19"]
InquiryType:["A"]
MaterialNo: ["34"]
Material Name: ["lamp"]
InquiryDocument No: ["0010000018"]
}
]
Here In this response the details such as Inquiry date and inquiry documentno, inquiry type are fixed as header details and need to be displayed as header table whereas material no and material name are item details need to be displayed in another table on click the corresponding inquirydocument no it should display all related item details for it.
Eg: InquiryDocumentNo: 0010000015 appears two times in the response I need to be displayed it as one time in header table and on clicking a buuton details it should display the 2 item(Bag, Book) inquired in another table.
I am trying to check if the documentno is same in the response array and trying to push the corresponding item details in another array in my code(appcomponent.ts) but it is doing correctly can anyone help me to figure it out and how to do this
inq =[];
for(var i=0;i<array.length;i++)
{
var element=array[i];
for(var j=i+1;j<array.length;j++)
{
var elt =array[j];
if(element.inquirydocno==elt.inquirydocno)
{
this.inq.push(elt.Materialno);
this.inq.push(elt.Materialname);
}
}
}
console.log(this.inq);
I had attached an image of how my output should be displayed
I'd recommend to use a dictionary for the 'details table'.
Something like this
export interface InquiryItem {
materialNo: string[];
materialName: string[];
}
inquiryItems: { [inquiryDocumentNo: string]: InquiryItem[] } = {};
// Manual populating
inquiryItems['001'] = [];
inquiryItems['002'] = [];
inquiryItems['001'].push({materialNo: '31', materialName: 'Book'});
inquiryItems["001"].push({materialNo: '31', materialName: 'Bag'});
inquiryItems["002"].push({materialNo: '30', materialName: 'Chair'});
// From response array
responseArray.forEach(entry => {
const docNo = entry.InquiryDocumentNo;
if(inquiryItems[docNo] === undefined)
inquiryITems[docNo] = [];
inquiryItems[docNo].push({
materialNo: entry.Materialno;
materialName: entry.Materialname;
});
})
// Retrieval:
docItems: InquiryItem[] = inquiryItems['0010000015'];

Testcafe - how do I iterate over selectors of different element types?

I have a React address form which is config driven, and each element could either be a text <input> or a <select> dropdown. When trying to fill in the form using the code below, the text inputs are populated successfully, but the select element can't be found. If I remove the select elements from the loop and select them individually afterwards, it works fine. The MOCKS.deliveryAddress values are just strings.
const addressFields = {
addressLine2: Selector('[data-testid="input-addressLine2"]'),
addressLine1: Selector('[data-testid="input-addressLine1"]'),
addressLine3: Selector('[data-testid="input-addressLine3"]'),
addressLine4: Selector('[data-testid="input-addressLine4"]'),
postalCode: Selector('[data-testid="input-postalCode"]'),
};
const fieldConfig = {
addressLine1: 'text',
addressLine2: 'text',
addressLine3: 'text',
addressLine4: 'select',
postalCode: 'text',
};
const enterAddress = async () => {
await Promise.all(
Object.keys(addressFields).map(async (field) => {
if (fieldConfig[field] === 'text') {
if (MOCKS.deliveryAddress[field]) {
await t.typeText(
addressFields[field],
MOCKS.deliveryAddress[field],
{
replace: true,
},
);
}
} else {
await t.click(addressFields[field]);
await t.click(
addressFields[field]
.find('option')
.withText(MOCKS.deliveryAddress[field]),
);
}
}),
);
};
}
I get the error 1) The element that matches the specified selector is not visible.
Am I doing something wrong here in how I handle the selector inside a map?
Thanks in advance!
According to the TestCafe documentation, the element is considered as 'visible' if it does not have display: none or visibility: hidden CSS properties and has non-zero width and height. Using the browser development tool to investigate the properties of elements used in tests.
Turns out I was doing it wrong! I should have been chaining the click events for opening the dropdown and selecting an option, rather than awaiting the select click and then awaiting the option click. E.g.
await t
.click(addressFields[field])
.click(
addressFields[field]
.find('option')
.withText(MOCKS.deliveryAddress.addressLine4),
);

react-select with selectable group labels

Is there a way to have the group labels in react-select selectable? I want to be able to do a search, have all of the relevant items to show in addition to their group label, and be able to click and select the group label (which has it's own ID value).
Here is exactly what you are looking for.
https://github.com/JedWatson/react-select/pull/2659#issuecomment-450700209
loadOptions = (value) => {
return this.getSuggestions(value).then(
rsp => {
const suggestions = this.filterGroupedSuggestions(rsp.data)
const creatable = {
label: `Search "${value}"`,
value: value,
group: 'search'
}
return [creatable, ...suggestions]
}
)
}

Resources