Clicking a link within nested tables using page-object - watir-webdriver

I have a link that is nested withing layers of tables and most of the table do not have any id. The link that I have is under a which is under a table that contains an id. I am unable to click the link no matter what. Here is the html. Please help. Thank you!
<html
<frame src="my_frame"
<html
<table style="height:28px;"
<table style="height:28px;"
.
.
<table style="height:28px;"
<table id="tblButtons"
<td id="" title="" onmouseover="this.className = 'hdrBtn hdrBtnover';" onmouseout="this.className = 'hdrBtn';" onmousedown="this.className = 'hdrBtn hdrBtndown';" onmouseup="this.className = 'hdrBtn hdrBtnover';" background="../images/header/barbkg.gif" onclick="if(pageIsReady())parent.ordersummaryform.SubmitIt('OK');" class="hdrBtn">Desktop</td>
Desktop
I have tried using xpath as below:
link( :desktop_header, :xpath => "a[#href='#' and #class='linkForTabbingOnly' and starts-with(text(),'Desktop')]")
and
link( :desktop_header, :xpath => "//table[#id='tblButtons']//a[#href='#' and #class='linkForTabbingOnly' and starts-with(text(),'Desktop')]")
I also tried
I tried
table(:table_button) {frame_element(:src => 'quotesummary_buttons.cfm?QuoteFormat=').table_element(:id => 'tblButtons',:href => '#', :class => 'linkForTabbingOnly' ) }
def click_desktop()
table_button_element.cell_element(:class => 'hdrBtn')
.child
.link_element(:text => 'Desktop')
.click
end
and used click_desktop to click the link but I get an error
NoMethodError: undefined method `frame_element' for #

Based on your partial HTML and attempts, I would guess that the crux of the problem is the frame:
The first couple of attempts are not taking into account the frame. Unlike other elements, you have to specifically tell Watir when to look in a frame.
In one of the latter examples, the frame is considered. However, as the exception says, using frame_element does not exist for defining frames.
The Page-Object gem wiki page has a good explanation on how to work with frames.
The HTML provided seems a bit fragmented, so you may need to make some adjustments to the following suggestions. However, hopefully with the wiki page information and a couple of more specific examples, you can resolve your issue.
The first step would be to ensure that the link accessor is being told to look in a frame:
class MyPage
include PageObject
in_frame(:src => 'my_frame') do |frame|
link(:desktop_header, :href => '#', :class => 'linkForTabbingOnly', :text => /^Desktop/, :frame => frame)
end
end
Unless there are multiple links in the frame with text "Desktop", I would probably suggest simplifying the link locator to just the text - ie the href and class attributes do not appear to add anything.
class MyPage
include PageObject
in_frame(:src => 'my_frame') do |frame|
link(:desktop_header, :text => 'Desktop', :frame => frame)
end
end
If there are multiple "Desktop" links on the page, but only one such link in the "tblButtons" table, then you can use nesting. In the below example, the table is located within the scope of the frame by using the :frame locator. The link is then located within the table by using a block and the nested element methods.
class MyPage
include PageObject
in_frame(:src => 'my_frame') do |frame|
table(:table_buttons, :id => 'tblButtons', :frame => frame)
link(:desktop_header) { table_buttons_element.link_element(:text => 'Desktop') }
end
end
While the concept of the above examples should work, there is a good chance that they will fail give the partial HTML provided. You might need to make some changes:
These examples assumed that the :src attribute of the frame is "my_frame", which is what is shown in the question's HTML sample. However, one attempts in the question suggest that the :src is actually "quotesummary_buttons.cfm?QuoteFormat=". Therefore, you should ensure that the correct :src (or other locator) is correct in the in_frame(:src => 'my_frame').
That there is a frame element in the html element seems unusual. If I recall correctly, frames are only allowed in frameset elements. It maybe possible that you are actually dealing with an iframe instead of a frame. If so, you will need to change the in_frame methods to in_iframe. Note that either way, for the elements in the frame, the locator is still just :frame.

Generally speaking, you should try to avoid using the xpath. It's very brittle and your code will likely break quite quickly!
Try nesting the elements such as:
#browser.table(:id, /Buttons/).link(:class, /link/)
I think you would really benefit from reading through the walk through of defining different elements. It's pretty helpful!

Related

TYPO3 field helpers / hints / tips

since I'm pretty new to TYPO3 I'd like to know is there a possibility of adding simple text hints / tips below any type of field, something like this, for Nickname input field:
Thank you in advance!
Out of the box, not yet.
We are discussing a generic way to do so as we speak, but right now you'd need to create your own renderType for FormEngine.
Given the amount of PHP knowledge you have this is easy to intermediate.
Here are the steps:
Step 1: add your own formEngine Type class in ext_localconf.php
$GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'][1463078603] = array(
'nodeName' => 'ApparelCalculation',
'priority' => 40,
'class' => \T3G\Apparel\FormEngine\ApparelCalculation::class,
);
The number 1463078603 should be unique, so a good idea is to use the current unix-timestamp for that.
Step 2: Instruct your field to use that renderType
Add a TCA override file in YOUR_EXTENSION/Configuration/TCA/Overrides/tt_content.php (in this case we're overriding tt_content, thus the name. If you want to reconfigure another table in TYPO3, use the filename according to the tablename.
Add something along this:
$GLOBALS['TCA']['tt_content']['columns']['header']['config']['renderType'] = 'ApparelCalculation';
See how the renderType name is identical to what we registered in step 1.
Step 3: Render what you like to render
I'll add the configuration of my special case class here, but I will cover the important things later in this post:
It might be helpful for your case to copy from backend/Classes/Form/Element/InputTextElement.php since that seems to be the element you want to put your tip to.
<?php
namespace T3G\Apparel\FormEngine;
use T3G\Apparel\Calculation\Calculation;
use TYPO3\CMS\Backend\Form\Element\AbstractFormElement;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class ApparelCalculation extends AbstractFormElement
{
/**
* Renders the Apparel Calculation Table
*
* #return array
*/
public function render()
{
$resultArray = $this->initializeResultArray();
$calculator = GeneralUtility::makeInstance(Calculation::class);
$resultTable = $calculator->calculateOrder($this->data['databaseRow']['uid']);
$resultArray['html'] = $resultTable;
return $resultArray;
}
}
I won't focus on things outside the render()method, because that's just plain PHP.
It is important to call $this->initializeResultArray(); first, so TYPO3 can work its magic to gather all the data.
From here on I'd suggest to use xdebug to get a grip of what you have available in that class.
The amount of information is very dense, but you will have everything there you need to build even the craziest stuff.
Now that you know how everything plays together you might think about extending backend/Classes/Form/Element/InputTextElement.php with plain PHP, grab the result of the parent render() call and simply add your tip to it.
Enjoy :)

SugarCRM - Custom Print Layout

I created a model in SugarCRM and I need to print the details view. But this must be printed with a different layout.
It must have the company logo for example, if I just wanted do print the bean information, the default print would be sufficient, but I need something closer to a report, because this info will be given to the costumer.
I would like to know if there is a way to create a printing template, and if there is, how can I create one?
Thanks for your help, if you need more information please comment.
rfnpinto
Even in SugarCRM CE you can leverage the included Sugarpdf class, which is an extension of TCPDF.
If you have SugarCRM Professional you can find examples of this in the Quotes module. If not, you're flying blind, so I can give you the gist of it.
Using the Contacts module as an example, create /custom/modules/Contacts/views/view.sugarpdf.php with contents like the following:
<?php
require_once('include/MVC/View/views/view.sugarpdf.php');
/**
* this defines the view that will drive which PDF Template we use
*/
class CustomContactsViewSugarpdf extends ViewSugarpdf{
public function display(){
$this->sugarpdfBean->process();
$this->sugarpdfBean->Output($this->sugarpdfBean->fileName,'D');
sugar_die('');
}
}
Create /custom/modules/Contacts/sugarpdf/sugarpdf.pdfout.php with contents like the following:
$contact = BeanFactory::getBean($_REQUEST['record_id']);
if(empty($contact->id)){
sugar_die('Could not load contact record');
}
$name_str = "<p><strong>Name: {$contact->name}</strong></p>";
$this->writeHTML($name_str);
$this->drawLine();
}
function buildFileName(){
$this->fileName = 'ContactPDFOut.pdf';
}
}
From there, you can print a PDF document per your format if you hit the URI index.php?module=Contacts&action=sugarpdf&sugarpdf=pdfout&record_id=1234
Once that's working in the way you want, you can add a button the Contacts Detailview to access that URI more easily. Dig into /custom/modules/Contacts/metadata/detailviewdefs.php and find the existing buttons array. It'll look something like this:
'buttons'=>array('EDIT', 'DUPLICATE', 'DELETE', 'FIND_DUPLICATES'
Just enhance this with your own button and hidden input
'buttons'=>array('EDIT', 'DUPLICATE', 'DELETE', 'FIND_DUPLICATES',array(
'sugar_html'=>array(
'type' => 'submit',
'value' => '(Wrongfully Hardcoded Label) Print PDf',
'htmlOptions'=>array(onclick => 'this.form.action.value=\'sugarpdf\';this.form.sugarpdf.value=\'pdfout\'')
)
)
...
The hidden array should be part of $viewdefs['Meetings']['DetailView']['templateMeta']['form'] and defined like so:
'hidden' => array('<input type="hidden" name="sugarpdf">'),
I haven't tested this recently but this is the general idea of adding custom Print PDF abilities to any particular screen within SugarCRM. TCPDF options are pretty extensive and forming the template just right is going to be very tedious, but I think once the "plumbing" is working here you'll figure that bit out, but feel free to ask followup questions.

Displaying Float on Input Forms

I'm fairly new to the CakePHP game and need some insight on how to resolve a seemingly simple issue. I've inherited a few internal websites at my new job that utilize the framework and am struggling to tackle this issue with Google alone.
What I have is a view that loads a form and populates it with data already in the database. There are three fields that have this behavior and all have the same issue.
The fields are declared as such on the View:
echo $this->Form->input('hotel_costs');
echo $this->Form->input('misc_costs');
Within the database they're declared as float DataTypes and therefore, when loaded to the browser will sometimes display as floats do: (15.7 becoming 15.699999999...)
Looking around it seems there are Helpers such as NumberHelper able to tackle my issue but I have no clue how to include the functionality with the form values. Am I looking in the wrong place entirely?
Thanks!
It has nothing to do with forcing the input type to text. Are you saying that you don't want the float's value in the field, but you want a rounded (to how many decimal places) number instead? It would have to apply across the board. Do you have a custom view or a baked one?
(I'd ask these as comments to your question, but my rep aint high enough.)
you can try to force input[type=text], so that cake doesn't try to guess input type.
$this->Form->input('hotel_costs', array(
'type' => 'text'
));
$this->Form->input('misc_costs', array(
'type' => 'text'
));
if this still doesn't work, post back with more details.
Which Controller Action(add/index/edit)?
Code of that action
var_dump() of data from the database

Uploading multiple files using Zend_Form_Element_File and HTML5's multiple attribute

I want to upload multiple images using Zend_Form_Element_File with the HTML attribute multiple. Setting up the element works intuitively:
$form->addElement(new Zend_Form_Element_File(
'images',
array('label' => 'Images:', 'multiple' => 'multiple')
));
When I get a reference to the input field in my upload page und do a $input->receive(), it only saves one of the selected files.
When I search for something like "Zend_Form_Element_File multiple files", I only get results that show the use of Zend_Form_Element_File::setMultiFile(), which isn't what I'm looking for.
Any suggestions?
Just found the answer to my own question:
You have to set 'isArray' on the input element to true, either in the options array when constructing the element (new Zend_Form_Input_File('images', array('isArray' => true))) or via the isArray() method ($input->setIsArray(true)).
Some background info and how I finally found this solution:
First, I realized that I have to apend square brackets to the element's name for multiple file uploads to work, e.g. images[]. I don't know if that's the HTML specification or if that's something PHP requires, but that's how it should work in this case.
My next problem was that Zend_Form_Element removes the brackets when I try to set them with the name property. Finally, I stumbled upon the answer by Matthew Weier O'Phinney himself: isArray appends the [] for you.

Why does the '#weight' property sometimes not have any effect in Drupal forms?

I'm trying to create a node form for a custom type. I have organic groups and taxonomy both enabled, but want their elements to come out in a non-standard order. So I've implemented hook_form_alter and set the #weight property of the og_nodeapi subarray to -1000, but it still goes after taxonomy and menu. I even tried changing the subarray to a fieldset (to force it to actually be rendered), but no dice. I also tried setting
$form['taxonomy']['#weight'] = 1000
(I have two vocabs so it's already being rendered as a fieldset) but that didn't work either.
I set the weight of my module very high and confirmed in the system table that it is indeed the highest module on the site - so I'm all out of ideas. Any suggestions?
Update:
While I'm not exactly sure how, I did manage to get the taxonomy fieldset to sink below everything else, but now I have a related problem that's hopefully more manageable to understand. Within the taxonomy fieldset, I have two items (a tags and a multi-select), and I wanted to add some instructions in hook_form_alter as follows:
$form['taxonomy']['instructions'] = array(
'#value' => "These are the instructions",
'#weight' => -1,
);
You guessed it, this appears after the terms inserted by the taxonomy module. However, if I change this to a fieldset:
$form['taxonomy']['instructions'] = array(
'#type' => 'fieldset', // <-- here
'#title' => 'Instructions', // <-- and here for good measure
'#value' => "These are the instructions",
'#weight' => -1,
);
then it magically floats to the top as I'd intended. I also tried textarea (this also worked) and explicitly saying markup (this did not).
So basically, changing the type from "markup" (the default IIRC) to "fieldset" has the effect of no longer ignoring its weight.
This sounds pretty strange because the manipulation of the form elements' #weight parameter always works reliably for me as advertised. One thing to note, though, is that the weights only affect the order relative to the elements siblings, so if the element you want to move around is on a level below that of the other elements, you'd have to change the weight of the parent element that is on the same level as the ones you want to move against.
To clarify, if you have a hierarchy like so,
$element['foo'];
$element['bar'];
$element['bar']['baz']
you can not move 'baz' relative to 'foo' by setting the weight of 'baz'. You'd have to either set the weight on 'bar' (moving it also), or pull out 'baz' and bring it to the same level as 'foo'.
Another possible reason could be CCK: If you have CCK installed, it allows you to set the order of its own as well as other fields under admin/content/node-type/<yourNodeType>/fields. It changes the order by registering the pre-render callback content_alter_extra_weights(), so this would run after your changes in hook_form_alter.
Edit: Update to answer the question update
The markup field type has a special behavior when used inside fieldsets, which is hinted on in the forms api documentation:
Note: if you use markup, if your content is not wrapped in tags (generally <p> or <div>), your content will fall outside of collapsed fieldsets.
It looks like if it does not only fall outside of collapsed fieldsets, but also refuses to respect the weight in those cases. Wrapping the content of the markup field in <p> tags makes it respect the weight on my machine:
$form['taxonomy']['instructions'] = array(
'#value' => "<p>These are the instructions</p>",
'#weight' => -1,
);
Sometimes (or always, when weighting CCK elements) the line that works in your hook_form_alter or $form['#after_build'] callback is this one:
$form['#content_extra_fields']['taxonomy']['weight'] = 5;
Wanted to insert a <div> I could use in JS. This didn't work for me:
$form['you_as_reviewer']['ui_container'] = array(
'#type' => 'markup',
'#value' => '<div id="le_reviewer_tags_ui"/>',
'#weight' => 5,
);
Weight was ignored.
This worked:
$form['you_as_reviewer']['ui_container'] = array(
'#type' => 'markup',
'#prefix' => '<div>',
'#value' => '<div id="le_reviewer_tags_ui"/>',
'#suffix' => '</div>',
'#weight' => 5,
);
Added prefix and suffix.
I do not quite understand what it is you want to achieve. Could you maybe clarify? Do you want to change the position of the taxonomy's drop-down on the page?
In the mean time you could install the Drupal Devel module (if you haven't done so yet). Then enable "Display form element keys and weights" from Admin > Devel Settings.
This should help you to debug your problem.
Edit after feedback:
I looked into it some more. The taxonomy weight is set in taxonomy.module on line 556 (Drupal 6.12):
$form['taxonomy']['#weight'] = -3;
To test I also implemented hook_form_alter for my module like this:
function mymodule_form_alter(&$form, $form_state, $form_id) {
...
$form['taxonomy']['#weight'] = -9;
...
}
This works for me i.e. it moves the taxonomy drop-down to the top of the page. I can change the weight and it moves accordingly on the rendered page.
Since you said you tried setting $form['taxonomy']['#weight'] in your original post I can currently think of only two possible checks:
Make sure the cache is cleared before testing. (you can use the Devel module for this)
Check to see if your hook_form_alter is called after taxonomy_form_alter
I you post the code you currently have we could look at it in more detail.
Please note: the weights displayed by the Devel module are not very useful for this situation. The weights of the elements on the "sub-forms" are displayed and not the weight of the "sub-form" itself. E.g. when I set $form['taxonomy']['#weight'] = -9; the -9 is not displayed by the Devel module but rather the weights of the elements inside $form['taxonomy'].
Have you specified the weight of another field and now your node form is not organized properly? The form api is kinda touchy and altering the form can result in things getting mixed up. I sometimes have to reassign a weight to my submit/preview buttons to get them back at the bottom of the form where they belong.
Just to cover all bases, make sure that you are clearing your cache as necessary. Drupal stores forms in it's cache by default, if you have the caching module enabled.
This is working for me
$form['forgot_password']['#markup'] = '<div class="text-align-right"><a class="text-primary" href="/user/password" target="_blank" title="Forgot Password?">Forgot Password?</a></div>';
$form['forgot_password']['#weight'] = 3;