Salesforce's iframes - testing

In order to support new lightning of salesforce, I'm trying to rewrite existing e2e tests. We have an integrated app, which opens in inframe in both cases (classic design and new lighting). In the case of old site design, we have to dig into the second level of nesting
<iframe ...>
...
<iframe id='my app'>
In the case of the newest design, yet another one level of nesting was added (my iframe is also in the deep).
I'm facing the problem, that I'm not able to switch to the second iframe. I always get "The iframe in which the test is currently operating does not exist anymore." Even if I want to await the simplest Selector with "div" element for example.
await t.expect(Selector('div').find('iframe').exists).eql(true);
await t.switchToIframe(Selector('div').find('iframe'));
const nextIframe = Selector('div');
const dom = await nextIframe(); <--- here it throws
I've checked the the first one selector, it returns exactly what I want.
What can cause my problem?

Related

How does testcafe decide an iframe has loaded?

I'm currently on the latest package 1.18.4 and having issues switching to an iframe during test execution.
Each time t.switchToIframe() is called, the following error is displayed:
Content of the iframe in which the test is currently operating did not load.
This happens even though i can clearly see the iframe has loaded, even placing a length wait of 60 seconds when landing on the page for testing purposes.
This rough code below should be runnable and reproduce the problem:
import { Selector, t } from "testcafe";
fixture(`Quick Test`);
test
.page(`https://www.terrific.ie/dealer/bradys-of-castleknock/finance/45784/13295`)(
`Quick Test`,
async () => {
await t
.click(`.submit-outer`)
.expect(Selector(`.car-summary-box`).visible)
.ok()
.expect(Selector(`.cw-finance-plugin.plugin-loaded`).visible)
.ok()
.switchToIframe(`.cw-finance-plugin.plugin-loaded`)
.click(`.cw-checkmark`)
.debug();
});
In general, there are two steps to switch to iframe. The first step is getting a selector with an iframe, but if the selector doesn't exist, you will get another error. The next step is getting contentWindow with a native getter. The error probably occurs on this step, but I can't reproduce this case with your iframe example. Could you share a full test example that illustrates this error?
Also, you put the content of the iframe between the tags, but it doesn't work like this. You need to set the path to the document in the src attribute of the iframe.

Selenium tests fail with azure pipeline sometimes and pass locally

Test cases fail while not finding a link or any validation messages after a button click.
I used explicit waits for page to load:
var waitForDocumentReady = new WebDriverWait(WebDriver, TimeSpan.FromSeconds(10));
waitForDocumentReady.Until((wdriver) => (WebDriver as IJavaScriptExecutor).ExecuteScript("return document.readyState").Equals("complete"));
For wait specific div of validation messages:
WebDriverWait wait = new WebDriverWait(WebDriver, TimeSpan.FromSeconds(10));
wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementExists(By.ClassName("validationErrors")));
But test cases pass sometimes with pipeline and fails sometimes.
I would recommend following:
When ever your tests fail take a snapshot at that moment.
sometimes when you run your tests locally the network communication
is a bit faster than running on server. Which means a spinner or a
loading control may not appear locally because results were retrieved
fast enough but the loader will appear when there is delay from
server in sending the response to client.
If you are trying to run your tests in FF headless on remote grid
setup then it is not yet stable in my experience.
Identify the pattern in failed scenarios which frequently fail and
try and run them multiple times in a loop and identify the pattern of
failure. In one of my case there was an actual bug in the performance
of the application which used to get reproduced whenever the tests
ran immediately in bulk
I was having this issue, except my test would always fail in Azure Pipelines but pass locally. Not running in "headless" mode fixed my problem. To do this, make sure "Test mix contains UI tests" is checked in your "Visual Studio Test" task.
There are a couple of things you need to take care as follows:
Test cases fail while not finding a link or any validation messages after a button click: A lot depends on the attributes of the button. In case the button contains either of the following attributes/events the DOM Tree would be getting updated and subsequently trying to find the desired element may fail:
onclick() event:
<button onclick="myFunction()">Click me</button>
jQuery click() Event:
$("p").click(function(){
alert("The paragraph was clicked.");
});
So after a button click, to find the desired element you need to induce you have to induce WebDriverWait for the ElementExists().
You can find a relevant discussion in ExpectedConditions.ElementIsVisible returns TimeoutException even when element is present
ExecuteScript("return document.readyState").Equals("complete"): This line of code is not that effective to ensure if the desired element(s) are present/visible/interactable with in the HTML DOM.
You can find a relevant discussion in Do we have any generic function to check if page has completely loaded in Selenium
However to wait for specific div with ElementExists() should have worked. The relevant HTML would have helped us to analyze what went wrong. However, if the validationErrors related element is based on HTML5 Constraint validation then you have to use the GetAttribute() method.
You can find a relevant discussion in How to handle html5 constraint validation pop-up using Selenium?

Modify External Browser Element via Vb.Net

Is that anyway to Modify firefox (or other browser) element with Watin/VB.Net after it open?
For example, I have a blank html page, then i open that page with Watin. Because its blank so no element loader. Then i want to add element to that page (form or link or image). Is that possible?
Or is it possible to done with memory editing? or maybe javascript?
so far the closest thing that i can find is this javascript
<button onclick="openTab()">Open</button>
<button onclick="closeTab()">Close</button>
<script>
var TAB;
function openTab() {
TAB = window.open("", "TAB");
TAB.document.write("<p>hi</p>")
}
function closeTab() {
TAB.close();
}
</script>
but its work change the elemnt of its own page, if use another URL its not work, and also its not vb. net XD
The following is functional code to modify a web page (any web page) using WatiN. You will be modifying the local copy you have locally, not the one on the server, of course. You can go as crazy as you want but you need to be more specific on what you want to achieve:
var browser = new IE();
browser.GoTo("about:blank");
browser.WaitForComplete();
browser.Eval(#"document.write('This is new text on the web page<br>')");
browser.Eval(#"var buttonnode= document.createElement('input');");
browser.Eval(#"buttonnode.setAttribute('type','button');");
browser.Eval(#"buttonnode.setAttribute('name','sal');");
browser.Eval(#"buttonnode.setAttribute('value','New Button');");
browser.Eval(#"document.body.appendChild(buttonnode);");

How to perform feasible web smoke test with Selenium WebDriver?

I have been doing some research on feasible and faster web page loading test with Selenium. A general idea of smoke testing is to click and navigate through the whole site to make sure the pages load properly. I was initially thinking to use some kind of ways to capture the http status code through some kind of http libraries since Selenium does not have any native support for that. But, I found it is not what I want since it will simply return Each and Every links of the site and most of them will be the ones I do not want. So the best way will be to perform actual click and take pages in return. The problem there is the execution time it will take. However, that’s what I am doing currently. Splitting the whole application into different modules and click through all VISIBLE links and take page objects in return with known selector. I am using FindElements() method to grab all the links of a page and click back and forth to test page load. I am doing something like the following:
Is there a better way to improve the performance?
WebElement deliveredChartDailyFocus = driver.findElement(By.id("delivered-chart-daily"));
deliveredChartDailyFocus.click();
// Get a list of all the <rect> elements under the #delivered-chart-daily element
List<WebElement> children = deliveredChartDailyFocus.findElements(By.tagName("rect"));
WebElement elementToClick = null; // variable for the element we want to click on
for (WebElement we : children) // loop through all our <rect> elements
{
if (we.isDisplayed())
{
elementToClick = we; // save the <rect> element to our variable
break; // stop iterating
}
}
if (elementToClick != null) // check we have a visible <rect> element
{
elementToClick.click();
}
else
{
// Handle case if no displayed rect elements were found
}
I would never call process of verification of every single link 'smoke testing'. For example how ISTQB defines this "A subset of all defined/planned test cases that cover the main functionality of a component or system, to ascertaining that the most crucial functions of a program work, but not bothering with finer details". And ths actually mean to exacute some meaningful scenarios and check some small flow/piece of functionality. Only clicking every link will check correctness of links but not computations or logic performed by server side. As for improving speed of passing tests you can consider running tests in parallel.

How to get WatiN to scan dynamically loaded content?

The situation is that I have a page that uses some AJAX calls to retrieve content from the server, then puts those results into a chunk of html generated by another script. The problem is, I can't select with watin any of the elements of this new piece of html. It can be viewed in the browser, and comes up when I hit F12 and scan through the code, but still WatiN can't see it.
Is this because WatiN only scans through the html source of the page, and not the current version of the HTML? I think a similar situation would be:
html -
<script type="text/javascript">
$('#foo').html("gak");
</script>
...
<div id="foo">bar</div>
then when I try and assert -
Assert.IsTrue(browser.Div("foo")).ContainsText("gak"));
it will return false.
Any ideas on this? or is my best option to just write a bunch of jQuery, and browser.Eval() it?
I test AJAX pages quite a bit. The key is to wait until the asnyc postback has completed. If you have
Assert.IsFalse(browser.Div("foo")).ContainsText("gak");
browser_action_that_changes_bar_to_gak
>> Here you need to wait <<
Assert.IsTrue(browser.Div("foo")).ContainsText("gak");
In the "wait" section you can do a System.Threading.Thread.Sleep(numberOfMilliseconds) <- this is not the best way, but it is really simple. Once you determine that waiting is what you need to do, a better way to wait is to poll the status rather than way numberOfMilliseconds each time. I believe different AJAX libraries do things differently, but what works for me is really similar to this: http://pushpontech.blogspot.com/2008/04/ajax-issues-with-watin.html
I put the JavaScript into an Eval() in a helper function in the my base Page class rather than having to inject it into every page like the article did.
.
my Base Page class contains:
public bool IsInAsyncPostBack()
{
const string isAsyncPostBackScript = "Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack()";
return bool.Parse(this.Document.Eval(isAsyncPostBackScript));
}
And then my WaitForAsyncPostback is basically the same as in the linked post, but I added a max wait time. Before going to Page classes (awesome; do it!) I made these static functions somewhere else and it worked too.
This is almost surely a timing issue. The jQuery has not updated when you test. Rather than introducing any artificial pause or wait it's best to wait for something to show that your AJAX has worked as expected.
In this case a WaitUntil should do the job nicely:
Assert.IsTrue(browser.Div("foo")).WaitUntil(c => c.Text.Contains("gak")));
This works for most updates and the like. Another common waiting pattern is on data loading say, where you'd have a spinning wheel displayed. Then you could wait until this wheel is gone with a something like:
WaitUntil(c => c.Style.Display == "none");