I am trying to download information from a website and I have hit (yet another) brick wall in a long and tiresome journey to get something productive developed.
I have a program which uses WebBrowser to login to a site - with a valid username and password - therby allowing me to set up a legitimate connection to it and retrieve information (my own) from it.
From the initial page presented to me after login, I can use WebBrowser.Document.GetElementsByTagName("A") and WebBrowser.Document.GetElementById("Some Id") etc. to work my way around the website, and processing all the DocumentCompleted events returned until ... I arrive at a page which appears to have a TabControl embedded in it.
I need to be able to choose the middle Tab of this control, and retrieve the information it holds. When I access this information 'normally' (i.e. from IE and not from my WebBrowser program) I can click each of the three tabs and information duly appears - so its there, tantalisingly so ... but can I manupulate these Tabs from my program? I feel it should be possible, but I can't see how I can do it.
The problem manifests itself because when I am processing the page which has the Tab in it my code looks like this:
static void wb_TabPage(object sender, WebBrowserDocumentCompletedEventArgs e)
{
WebBrowser wb = (WebBrowser)sender;
HtmlElement element;
element = wb.Document.GetElementById("Bills"); // Find the "Bills" tab
element.InvokeMember("Click"); // Click the "Bills" tab
// Unhook THIS routine from DocumentCompleted delivery
wb.DocumentCompleted -= new WebBrowserDocumentCompletedEventHandler(wb_TabPage);
// Hook up this routine - for the next 'Document Completed' delivery - which never arrives!
wb.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(wb_Bills);
return;
}
And that's the problem - no more Documents are ever 'Completed' for me to process, even after the InvokeMember("Click"). It seems for all the world that the Tabs are being updated inplace, and no amount of Refresh(ing) or Navigating or Event Handling will allow me to get to a place or in a position where I can get the data from them
Does anybody have any idea how I can do this? Does anybody know how to manipulate Tabs from WebBrowser? Thanks in advance if you do ...
Try using the findcontrol function on your page. You will likely need to drill into the tab control itself to find the tab page and the controls contained in it.
Related
I have multiple pages in my applications, one of them is to add a driver information.
When i go to add driver information page and fill some of the fields like "driver licence" text box, then i do not add this to DB and click "go back" button (that discard the changes and come back to home page) when i enter again to this page the fields that i have previously filled in with data do not clear and refresh (its supposed to all fields be clear and empty)
Does anyone have a solution for that?
code for "go back button:
app.datasources.driver.clearChanges(function() {
console.log("cleared changes");
});
returnToDriver();
returnToDriver() code is:
app.datasources.DRIVERS_LIST.query.clearFilters();
app.datasources.DRIVERS_LIST.load();
app.showPage(app.pages.Driver);
Already tried:
widget.root.descendants.TextBox1.value = "";
widget.root.descendants.TextBox1.value = null;
but do not work for me.
Regards
Potentially there are can be multiple ways to leave the page:
browser navigation including navigation hotkeys
links on the page that can navigate to other pages
in-app navigation buttons/hotkeys
etc...
The best way to handle all possible navigation scenarios is using onDetach page event
// Implicit way
// page onDetach event handler, assuming that page
// is bound to appropriate datasource:
// #datasources.<MyDatasource>.modes.create
widget.datasource.clearChanges();
// Explicit way
// Explicitly clearing changes for create datasources in
// page onDetach event handler
app.datasources.<MyDatasource1>.modes.create.clearChanges();
app.datasources.<MyDatasource2>.modes.create.clearChanges();
...
Once you add this code to the onDetach page's event handler you can remove all other clearChanges occurrences from the page.
I'm testing a functionnality on a website that allows the user to fill a form. At a moment, the users needs to click on a button, which triggers an Ajax loaded modal that allows him to upload a file. However, when I trigger the button, Behat doesn't seem to "see" the modal window.
Maybe I should precise I'm in a Drupal 8 environment, but I don't know if this changed anything
Just so we're clear, I'm not talking about an alert, but this kind of modal
So far my tests looks like this:
Scenario: Creates a stage test with two sessions
Given I am on "/user/login"
And I fill in "user#user.com" for "name"
And I fill in "password" for "pass"
And I press "Log in"
Then I should get a "200" HTTP response
And I should see "User Name"
When I go to "/node/add/stage"
Then I should get a "200" HTTP response
And I should see "Add content CISIA Stage"
When I fill in "Test Cisia Stage" for "edit-title-0-value"
And I press "Select files"
Then I should see "Upload files" <-- fails
And I should see "Click or drop files here to upload them" <-- gets ignored but is likely to fail too
I can't find anything modal-related on SO or Google in general, only about small message alerts, and people talk about objects or functions I don't have (such as getWebDriver())
I also tried to find the modal's content by myself by doing so:
public function iShouldSeeAModalWindow() {
$element = $this->getSession()->getPage();
$modal = $element->find('css', sprintf('div:contains("%s")', 'Upload files'));
if($modal) {
exit('Yaaaay!');
}
else {
throw new Exception("No modal found");
}
}
However I got no luck so far.
What should I do?
You have an iframe and you need to switch to it.
Use something like this:
$this->getSession()->getDriver()->switchToIFrame('iframe_name');
I think you should also consider to write your scenario on a high level basis and also use page objects extension to avoid getting long scenarios that are hard to maintain and unreadable and also to reuse as much code as possible.
Follow Behavior Driven Development methodology.
So I would like to be able to have a print button for entries in our database so users can print an entry via a print friendly "form".
My thought was to create a separate page, add labels and have those labels pull the relevant information.
I know I can add the open widget information via this code:
app.datasources.ModelName.selectKey(widget.datasource.item._key);
app.showPage(app.pages.TestPrint);
But I'm running into a few problems:
I can't get the page to open in a new window. Is this possible?
window.open(app.pages.TestPrint);
Just gives me a blank page. Does the browser lose the widget source once the new window opens?
I can't get the print option (either onClick or onDataLoad) to print JUST the image (or widget). I run
window.print();
And it includes headers + scroll bars. Do I need to be running a client side script instead?
Any help would be appreciated. Thank you!
To get exactly what you'd want you'd have to do a lot of work.
Here is my suggested, simpler answer:
Don't open up a new tab. If you use showPage like you mention, and provide a "back" button on the page to go back to where you were, you'll get pretty much everything you need. If you don't want the back to show up when you print, then you can setVisibility(false) on the button before you print, then print, then setVisibility(true).
I'll give a quick summary of how you could do this with a new tab, but it's pretty involved so I can't go into details without trying it myself. The basic idea, is you want to open the page with a full URL, just like a user was navigating to it.
You can use #TestPrint to indicate which page you want to load. You also need the URL of your application, which as far as I can remember is only available in a server-side script using the Apps Script method: ScriptApp.getService().getUrl(). On top of this, you'll probably need to pass in the key so that your page knows what data to load.
So given this, you need to assemble a url by calling a server script, then appending the key property to it. In the end you want a url something like:
https://www.script.google.com/yourappaddress#TestPage?key=keyOfYourModel.
Then on TestPage you need to read the key, and load data for that key. (You can read the key using google.script.url).
Alternatively, I think there are some tricks you can play by opening a blank window and then writing directly to its DOM, but I've never tried that, and since Apps Script runs inside an iframe I'm not sure if it's possible. If I get a chance I'll play with it and update this answer, but for your own reference you could look here: create html page and print to new tab in javascript
I'm imagining something like that, except that your page an write it's html content. Something like:
var winPrint = window.open('', '_blank', 'left=0,top=0,width=800,height=600,toolbar=0,scrollbars=0,status=0');
winPrint.document.write(app.pages.TestPage.getElement().innerHTML);
winPrint.document.close();
winPrint.focus();
winPrint.print();
winPrint.close();
Hope one of those three options helps :)
So here is what I ended up doing. It isn't elegant, but it works.
I added a Print Button to a Page Fragment that pops up when a user edits a database entry.
Database Edit Button code:
app.datasources.ModelName.selectKey(widget.datasource.item._key);
app.showDialog(app.pageFragments.FragmentName);
That Print Button goes to a different (full) Page and closes the Fragment.
Print Button Code:
app.datasources.ModelName.selectKey(widget.datasource.item._key);
app.showPage(app.pages.ModelName_Print);
app.closeDialog();
I made sure to make the new Print Page was small enough so that Chrome fits it properly into a 8.5 x 11" page (728x975).
I then created a Panel that fills the page and populated the page with Labels
#datasource.item.FieldName
I then put the following into the onDataLoad for the Panel
window.print();
So now when the user presses the Print Button in the Fragment they are taken to this new page and after the data loads they automatically get a print dialog.
The only downside is that after printing the user has to use a back button I added to return to the database page.
1.
As far as I know, you cannot combine window.open with app.pages.*, because
window.open would require url parameter at least, while app.pages.* is essentially an internal routing mechanism provided by App Maker, and it returns page object back, suitable for for switching between pages, or opening dialogs.
2.
You would probably need to style your page first, so like it includes things you would like to have printed out. To do so please use #media print
ex: We have a button on the page and would like to hide it from print page
#media print {
.app-NewPage-Button1 {
display : none;
}
}
Hope it helps.
1. Here is how it is done, in a pop up window, without messing up the current page (client script):
function print(widget, title){
var content=widget.getElement().innerHTML;
var win = window.open('', 'printWindow', 'height=600,width=800');
win.document.write('<head><title>'+title+'/title></head>');
win.document.write('<body>'+content+'</body>');
win.document.close();
win.focus();
win.print();
win.close();
}
and the onclick handler for the button is:
print(widget.root.descendants.PageFragment1, 'test');
In this example, PageFragment1 is a page fragment on the current page, hidden by adding a style with namehidden with definition .hidden{display:none;} (this is different than visible which in App Maker seems to remove the item from the DOM). Works perfectly...
2. You cannot open pages from the app in another tab. In principle something like this would do it:
var w=window.parent.parent;
w.open(w.location.protocol+'//'+w.location.host+w.location.pathname+'#PrintPage', '_blank');
But since the app is running in frame nested two deep from the launching page, and with a different origin, you will not be able to access the url that you need (the above code results in a cross origin frame access error). So you would have to hard code the URL, which changes at deployment, so it gets ugly very fast. Not that you want to anyway, the load time of an app should discourage you from wanting to do that anyway.
This question already has answers here:
How to pass data to the previous page using PopAsync?
(2 answers)
Closed 6 years ago.
in main page I have a button create post. When I click on it I receive editor. After input of some text I click button savePost. Then post saves to server and return to my main page, but without new post on my wall. I need to refresh that page to see my new post. How can I write code to receive my previous page with my new post on main page after clicking button savePost?
Button savePost = new Button {Text = "Save post"};
stackLayout.Children.Add(savePost);
savePost.Clicked += (sender, args) =>
{
var restService = new RestServiceImpl(UserService.User.AccessToken);
PostView post = new PostView
{
Text = textEditor.Text,
};
restService.CreatePost(post);
Navigation.PopAsync();
};
There are a few ways to go about it. The most simple one is to implement some mechanism on the OnAppearing event of the page and just reload there, or think of some way to detect a reload has to be done instead of just reloading. This can be done for instance by some bool you set to true after the 'restService.CreatePost(post);' line.
That kind of brings me to the other way. When you are using some kind of MVVM framework (have a look at FreshMvvm for example) you can execute some code when a PageModel is popped. So you have much more granular control over when to reload and detect if it is necessary at all.
A completely other way is to use the MessagingCenter. You can send out a message whenever (and from where ever) reloading is needed and let the pages which needs reloading subscribe to that and execute the reloading code whenever the right message was received.
It all depends on what your requirements and code structure is.
I would like to open a document after my ASP.NET page loads in a separate window. I would like to do this with the document not attempt to be blocked by a pop-up blocked. I tried and I am getting the prompt to ask if I would like to allow the popup. Is the best way to do this using a timer control or is there a better way in the lifecylce?
I have tried several events, but they are all launching the document prior to page load.
Fundamentally what you're trying to do is exactly the thing that pop-up blockers are designed to prevent - load a pop-up window without an explicit user interaction. There may be various tricks you could use to get around certain particular pop-up blockers, but you'll never be able to solve this in the general case.
The best solution is to have a link on your page to open the document in question in a new window. Pop-up blockers do not prevent links targeted to a new window.
I use
function openpage(page) {
if (document.getElementById('hf_open').value == 1) {
openChild(page, 'nueva');
document.getElementById('hf_open').value = 0;
}
}
and in the body onload ="openpage('whateverpage.aspx');"
and in an ASP.NET event I set if I want the popup to be open or not a particular time by setting hf_open to 1 if the pop up has to be opened at that time.
In Internet Explorer 7 with pop up blocker: turn on checked - it works.
How are users getting to your page? You could place the popup JavaScript in the link that takes users to your page.
You could use the onload JavaScript event.
function open_page()
{
popupWin = window.open('windowURL','windowName', ' resizable,dependent,status,width=500,height=400,left=0,top=0')
}
Then have the following body tag
<body onload="open_page()">
However, this won't get around your popup blocking issue.