Protractor .sendKeys() and browser.executeScript("arguments[0].textContent= arguments[1];", cell, value) do not work on non-input field - protractor

I am writing automated tests with Protractor and Jasmine in TypeScript, but I cannot modify conentents of non-input fields of a table.
I have already tried using Protractor .sendKeys() and browser.executeScript("arguments[0].textContent= arguments[2];", cell, value).
Protractor .sendKeys() fails to modify it as I wish, instead it creates "0" value in the cell.
browser.executeScript("arguments[0].textContent= arguments[2];", cell, value) does change the value in the cell, at least visually. However, once I try saving the changes with pressing "Save" button on the page, the change get discarded and the value of the cell return to default.
I also tried it without .click() and .sendKeys(). Does not work.
My code:
const index = await this.components.indexOf(componentName);
const cell = await element(by.css('[row-index="'+index+'"] [col-id="value"]'));
await cell.click();
await cell.sendKeys(value);
await browser.executeScript("arguments[0].textContent= arguments[1];", cell, value);
the DOM with the cell in question
The table itself
I expect the values to be modified and preserved after I modify them in the table and press "Save" button

Updated Answer:
Based on how you describe the user interaction in the comment I believe that sending the keystrokes to the browser should work for you in this instance.
const index = await this.components.indexOf(componentName);
const cell = await element(by.css('[row-index="'+index+'"] [col-id="value"]'));
const spanThatContainsValue = cell.element(by.tagName('span'));
//Click on the cell in order to set the focus on field
await cell.click();
//Send the keystrokes to the focused field
await browser.actions().sendKeys(value).perform();
//use delay while testing so you can manually check if entered in field
await browser.driver.sleep(10*1000);
Any issues let me know

In the end the following solution worked for me:
const index = await this.components.indexOf(componentName);
const cell = await element(by.css('[row-index="'+index+'"] [col-id="value"]'));
await cell.click();
await browser.switchTo().activeElement().sendKeys(value);
await cell.sendKeys(Key.ENTER);

Related

How to handle reading from database when API-request hasn't finished yet to save to database in Flutter?

For my App i'm loading the link for the background-image for each screen from my API.
Right after the query that downloads and saves the image-link, i'm querying the link from the database.
The problem now is, that the function isn't waiting for the download and saving to finish although i'm using await, therefor i get an empty result from the database and get an error from the imageloader.
Future<String> downloadAsset(String name) async {
final Map<String, String> _json = {
'mandant': Config.mandant,
'name': name
};
final query = MakePost('get_app_assets', false, _json, saveAsset);
await query.queryAPI(); // Function won't wait for this to finish
String ret = await dbAppAssets.getText(name); // Get link from database
return ret;
}
I've already tried to use .then(), but the same thing happens.
This only happens initially on the first call of each screen, but how is this normally beeing handled?
I'm using riverpod with futureProviders if that matters.
I do not know where you are using the downloadAsset function, but when you use Future on a function you should also await the function where you are using it, for example:
Future<void> _reverseScrollToTopAnimation() async {
await controller!.reverse();
_showBackToTopButton = false; // hide the back-to-top button
}
then, wherever you call it you should also await that function:
await _reverseScrollToTopAnimation();
If not the function will act as a synchronous operation even though you are using await inside the function.

ExpectedCondition elementToBeClickable pass but element.click fail

So I'm writing e2e test for an app and I have a method to fill up an input
static async fillInput(el, text = this.randomString()) {
await el.click();
await el.clear();
await el.sendKeys(text);
}
It works great. Well it worked great until I tried it on a field that appeared after clicking on a button. I got a Failed: element not interactable: element has zero size. Okay, maybe I4m a little hurry, so my function was updated to be that
async fillEmail() {
const newEmail = CommonMethods.createRandomEmail();
const emailElement = element(by.css('.block-info input[name="email"]'));
await browser.wait(protractor.ExpectedConditions.elementToBeClickable(emailElement));
await browser.sleep(5000)
await CommonMethods.fillInput(emailElement, newEmail);
return newEmail;
}
I reaaaaally thought it was a delay thing. But no. protractor.ExpectedConditions.elementToBeClickable pass, but fillInput failed with the same error while trying to click on the element.
I checked the css properties too, founc out line-height and font-size are set to inherit and parent has everything set up. width and max-width are set to 100%, element is clearly visible and I can click on it anywhere to get the focus.
Anyone has an idea ?

How can I detect a content control without the user selecting the whole thing?

Background
I've inserted a bunch of content controls into my word document. Each content control is a bit of text e.g. "Hello world".
What I'm trying to do
When a user puts their cursor within the content control I want to access the details of the content control within my add-in.
What I've tried
I run this at startup.
Office.context.document.addHandlerAsync(Office.EventType.DocumentSelectionChanged, () => {
Word.run( async (context) => {
const range = context.document.getSelection();
console.log({range});
const contentControls = range.contentControls;
contentControls.load("items");
await context.sync();
console.log('contentControls.items', contentControls.items)
})
})
Problem
If a user pops their cursor in the content control no "items" are reported. However if a user highlights the whole content control the "items" are correctly reported.
Question
Is there a way to detect if a user is within a content control without them having to select the whole thing?
Try using Range.parentContentControl (or parentContentControlOrNullObject) to get a reference to the containing content control.
For example,
const parentContentControl = range.parentContentControlOrNullObject;
await context.sync();
if (parentContentControl.isNullObject) {
console.log("The cursor is not in a content control")
}
else {
console.log('parentContentControl', parentContentControl);
}

How to defocus a cursor from an input text field in protractor

I have an input text field filled with date. I have to clear the date text and click cursor to somewhere on webpage or to some element to do other actions.
Now the problem is I am unable to move cursor to some other element or somewhere on webpage. Cursor remains on that input box once text is cleared
I have tried following ways:
mouseMove: I am trying to move cursor to somewhere on webpage and clicking it but not working.
blur() : used this one to loose the focus but not working.
var input = element(by.css('input[placeholder = "Choose a date"]'))
var someOtherElement = element(by.id('otherElement'));
input.click().clear().then((function) {
browser.actions().mouseMove(someOtherElement).click().perform();
});
Actual: Once date text is cleared, cursor remains on the text input. it is not moving from that text box.
Expected: I wanna cursor loose the focus and move to some other element and click it so that I can do some other actions.
Do you get any error stack for this? Would be great if you paste it here.
I am actually suspecting that someOtherElement does not exist or not clickable.
Can you give below snippet also a shot by making the function which have below code in it as async()?
var input = await element(by.css('input[placeholder = "Choose a date"]'));
var someOtherElement = await element(by.id('otherElement'));
await input.click().clear().then(() => {
someOtherElement.click();
})
.then(() => console.log('finished'));

Table.getCell() not working on cell in newly inserted row

I am trying to insert a new row to a table in Word and change the content of the cells in the new row. The problem that I am having is that after insertion of the row, the Word api is not able to find cells in the new row.
Below I added a very simplified version of my code.
await Word.run(async(context) => {
let table = context.document.body.tables.getFirstOrNullObject();
context.load(table, {
expand: "rows/items/cells/items/body"
})
await context.sync();
let row = table.rows.items[table.rowCount - 1];
row.insertRows("After", 1);
await context.sync();
let cell = table.getCell(2, 0); //throws "ItemNotFound" exception
cell.body.insertText("test", "Replace");
await context.sync();
});
Is there a way to get this working or is this a bug?
(please don't suggest using the values parameter on insert row as my actual code is much more complicated)
The reason this is happening is that you haven't reloaded the table object. You need to tell the API to explicitly reload table before the sync() will pick up that request:
let row = table.rows.items[table.rowCount - 1];
row.insertRows("After", 1);
context.load(table, {expand: "rows/items/cells/items/body"});
await context.sync();
Another way to approach this would be to load just the row you've added rather than reloading the entire table. You can do this by loading the tableRowCollection returned by insertRows():
let newRows = row.insertRows("After", 1);
context.load(newRows, { expand: "items/cells/items/body" });
await context.sync();
newRows.items[0].cells.items[0].body.insertText("test", "Replace");