Preface
I am currently coding Microsoft's Botbuilder SDK in Node.js.
The Problem
In the case of prompting the user to choose from a set of options that are clickable buttons, the text of the buttons get cut off with appended ellipses. Here is an example using Microsoft's Bot Framework Emulator:
Here is the code:
bot.dialog('mainMenu', [
(session, args, next) => {
// buttonOptions is an array of size 4 all with the
// string 'VERY LONG TEXT THAT GETS CUT OFF'
builder.Prompts.choice(session, 'What would you like to do?'
, buttonOptions, { listStyle: builder.ListStyle.button });
}
]);
The Desired Result
I would like to show the entire text of the buttons. I am aware that the listStyle: list exists that shows the entire text, but I am looking for a solution that allows button-use.
The Question
Is there a way to expand the buttons to show the entire length of long text in these types of prompts? Alternative perspectives not confined to this listStyle are welcome.
The way the choices are displayed is implemented by each channel, so you may concentrate on your target channel.
Some channels implementations (typically emulator and webchat) are open-source and you can create your own fork to build the behavior you need.
Emulator
Bot Framework's emulator sources are located on GitHub.
Webchat
I already replied to a similar question about customizing the webchat to display all the text of the buttons. To avoid duplicates, please have a look directly here: Using botbuilder SDK's Prompt.choice(), is it possible to have a custom tooltip which displays long choice-text?
It allow rendering buttons multiline like that:
You can add to the text "\n". So the button look it similar like this
Example
For a better result, I determined a maximum value and divided the string length. With this number I made a split. After I searched the last white space to put "\n".
Related
I am using chromeless API (https://github.com/graphcool/chromeless)
How can I select an option from a dropdown list?
Specifically I want to select last option having value="other".
My HTML is:
You could achieve this with the evaluate() method which lets you evaluate any Javascript within the browser-context of any page you load:
await chromeless
.goto('http://yourwebsite.com/yourpage')
.evaluate(() => {
select = document.querySelector('select.decline-form-select')
select.value = 'other'
})
Or, specifically select whatever the last item is in the select list:
await chromeless
.goto('http://yourwebsite.com/yourpage')
.evaluate(() => {
document.querySelector('select.decline-form-select option:last-child').selected = true
})
It can be done without the evaluate() method, too, albeit in a somewhat convoluted way. Avoiding evaluate() is useful when it is unknown exactly which events have to be triggered upon change, for the web application to work.
await chromeless
.click('#the-select-element')
.type('First characters of description text of desired option', '#the-select-element')
.click('#the-select-element option[value="the-matching-value"]')
Or using the example posted in the question:
await chromeless
.click('select.decline-form-select')
.type('Oth', 'select.decline-form-select')
.click('select.decline-form-select option[value="other"]')
Selecting an option using native Chromeless commands involves first clicking the select element, then typing text to select the desired option, based on the visible text content of the option (the first few characters that unambiguously identify the option should be enough), and then clicking the desired option element. Since it is not possible to find the option element by text content using css selectors, the element must be selected by some other means – e.g. value or ordinal number.
Sending arrow key presses instead of typing characters to select the option might work, but I found in my testing that using the press() method was buggy. (A tab with Chrome settings would open randomly while executing tests that used press() to send either the return or the space key.)
All this said, I was unable to make tests run reliably with Chromeless. There seemed to be problems related to scrolling elements into view or not. While the webdriver-based systems http://webdriver.io, http://nightwatchjs.org and https://www.npmjs.com/package/selenium-webdriver are a bit more complicated to set up and code for, it might be worth the effort in order to get better reliability.
I want to use the Watir to click a link that looks like a button attached the image.
I use the following method,but doesn't works:
#browser.div(:id,"NetworkAnalysisTabPanel").div(:index,1).div(:index,1).ul(:index,1).li(:index,1).link(:index,2).click
Note:
#browser.div(:id,"NetworkAnalysisTabPanel").div(:index,1).div(:index,1).ul(:index,1).li(:index,1).link(:index,2).flash
is working fine but click is not working in IE and FF
Link looks like this:
And HMTL like this:
Note: I am able to click on the element using selenium IDE with clickAt method
Try this (not tested):
browser.link(:class => "x-tab-strip-menu").click
If you can flash the link, but click does not do what you want, see this: How to find out which JavaScript events fired?
FYI what you have are links that are using standard background images controlled via CSS magic that keys on the class of the link to know what background to set. That's where the image comes from, and why you don't see it as part of the link in the HTML.
In that control, each tab is a list item element (li) in an unordered list (ul), and each list item has an ID, so that's the easiest way to tell it which tab you are trying to click inside.
Try identifying things starting with the LI that is the tab container, as within that container there is only one instance of each link of a given class. Of the 4 links, only one is without any kind of easy identifier, and if you need to click that one you'd need to use :index, but for the other 3 links using :class ought to work. This should result in code that is less brittle and subject to being broken if the order of tabs changes, or the page is refactored.
#browser.li(:id,"NetworkAnalysisTabPanel__ext-comp-1038").link(:class, "x-tab-strip-menu").click
If the number at the end of the ID is subject to change, you can try a regular expression to match the part you can predict and is unique from the others
#browser.li(:id,/NetworkAnalysisTabPanel__ext-comp-/).link(:class, "x-tab-strip-menu").click
If you can reliably identify the object and use .flash but .click does not seem to do anything, you may have to use .fire_event('onclick') instead or .click.
#browser.li(:id,/NetworkAnalysisTabPanel__ext-comp-/).link(:class, "x-tab-strip-menu").fire_event('onclick')
If that does not work, then you need to start experimenting with likely events that the control might be looking for (which will not necessarily show up in the HTML btw.. it may be in javascript or CSS etc)
UPDATE
This is where having an live example of the control that we can interact with is critical. doing some googling on the class names I was able to find one here and that let me play with it a little, and what I discovered is that it is looking for onmousedown. so, on that site, this works
browser.li(:id, 'TabPanel1__ctl07').link(:class, 'x-tab-strip-menu').fire_event('onmousedown')
Now since those ID's may not be the best identifier, a bit more digging (using .text on the li that holds the tab parts) found me some text, which in a menu like that ought to be unique.. SO, we can change this to make things a bit more robust and clearer as to what tab I'm clicking on (this will also be less subject to breaking if the tabs change around.
browser.li(:text, 'Menu 1').link(:class, 'x-tab-strip-menu').fire_event('onmousedown')
Lastly, since the click is causing client side code to execute, you may need a brief pause (a one or two second sleep) to wait for that portion of the page to re-render etc.
Our web application has some event code to "format" any text with pasted into a field so that any HTML styles do not break our data.
What would be a good way to pre-load the browser clipboard so that I can test pasting into the input field?
Is there any way to do it programmatic-ally or would I have the test script visit "a source page" and copy text before moving onto our application?
Any ideas or code snippets would be welcome.
Working with the clipboard will depend on your platform. E.g. on OS X, you can use pbcopy and Command-V:
open('|pbcopy', 'w') { |io| io << 'some text' }
browser.text_field(:name => 'q').send_keys([:command, 'v'])
I know there are equivalents on Linux (xclip?). Not sure about Windows.
I would consider using the .value= method to set the value. If it's been implemented the same as in watir, then it causes no events to be fired and sets the value directly, and then follow that up by sending an appropriate event (depending on what if any events are being monitored) such as onKeypress. I tried to figure out from the Watir-webdriver rdoc for textfield, if this distinction between .set and .value= has been maintained, but the way the doc describes them (at least there) makes them seem interchangable.. (Jarib can you clarify???)
Potentially you might need to first fire something like onFocus depending on the controls you are using. For example, as described in this SO case Setting a text field that has a JQuery mask on it for a jquery mask, they had to end up firing an unmask event to be able to even set the field.
This is a good case for utilizing the techniques described here How to find out which JavaScript events fired? and in the SO item linked in the comments for that question, to figure out just what events are fired when you manually paste something into a field. (note I would slueth it with both using the mouse, but also using something like tab to move between fields and set the focus, events common to those two methods are the ones most likely to be implemented by the controls.
I presume you have some kind of client side javascript that needs to check what was pasted into the field, and thus the reason for this test. If you are using standard HTML fields, with no javascript stuff, then I would consider this particular test case to be effectively the same as 'testing the browser' since supporting cut and paste in input fields is a standard browser function. In that case, you are sort of 'off the reservation' and I'd not bother with such a test case.
In my program I want the user to be able to choose between some options so I was using wxChoice component. Unfortunately after user interaction (clicking a button) I have to show custom text (not from my predefined list). Everything works fine if I use wxCombobox control but the drawback of this approach is that each time user selects an element from a list, selected text is highlited. It is annoying. I want the component to be read-only like. How to achieve this ?
Some code to visualize my question:
wxComboBox* viewAngle = wxDynamicCast( owner->FindWindow
( ID_CHOICE_3D_VIEWANGLE ), wxComboBox );
viewAngle->SetSelection( wxNOT_FOUND );
viewAngle->SetValue(_("Custom View"));
EDIT:
This control is used to set camera view in 3D object viewer application. Possible options are like: top, left, right, etc. It is also possible that the user moves 3D object using mouse. In that case I want my combobox to display "custom view" string. However "custom view" should not be a part of combobox list because selecting this option does nothing.
wxWidgets default implementation alwasy marks selected text. Which might be misleading for the user because he might think that he is expected to input any text.
IMHO, the custom text should be added to the wxComboBox control, the program could just ignore it when user selects that option.
Also, the wxComboBox's wxCB_READONLY style could be used to avoid the highlighting thing.
Hi
If any one knows how to use in-place warning message in MFC could you share info.
Is there a way to use it or is there any control we can use directly in mfc.
In-Place warning message: A warning message with appropriate icon along with warning message, will be displayed with in the same dialog.
I found some info about in-place message in msdn
InPlace message in msdn glossary
Different messages
Please share information.
Regards
Haranadh
From your comment, it appears that you're referring to this as an in-place message:
Ironically, of course, that's labeled as the incorrect example on the MSDN page that you link to. It's specifically recommended that you provide more specific advice, such as securing the projector with a password so that the presentation is not visible to unintended viewers. Putting that aside, however...
This is quite easy to implement in MFC. It's done simply with two STATIC controls, one on the left that displays an icon (in this case, a warning triangle) and the longer one on the right that displays static text (the warning message itself). If you're using the dialog editor to create your window, it's a simple matter of dragging the two controls to the dialog window and arranging them accordingly. There isn't a single control that encapsulates this functionality, but it's silly to expect that there would be, considering that doing it with two separate static controls is already so straightforward.
To load built-in icons such as the warning triangle shown above, you can use the LoadStandardIcon function and specify IDI_WARNING as the icon name. The complete list of values is available here. Obviously you can load any icon of your choosing as well; just add it to your project's resources.
Since you will presumably want to display the warning message only when it's applicable, you will need to programmatically hide and show the two controls depending on action taken by the user in your dialog. The standard ShowWindow member function makes this a trivial task. Call it on the two static controls, passing SW_SHOW as its argument if you want the warning message to be visible. Otherwise, you can specify SW_HIDE to hide the control.
As an alternative to what you are trying to do; you could place your message in a dialog:
int nResult = AfxMessageBox("Save changes to Current Job?", MB_YESNO);
if (nResult == IDYES)
{
OnFileSave();
}