Styles

Sunday, April 25, 2010

Telerik Smarts

RAD Alerts

To convert the standard Javascript Alerts to the fancy RAD Alerts add this script within the <Head> tag.

<script type="text/javascript">
  window.alert = function(string)
  {
    radalert(string.replace(/-/g, "<br />•"), "auto", null, "Alert");
  }
</script>

Add the RadWindowManager in the page and configure it with the appropriate Telerik Skin.

<telerik:RadWindowManager runat="server" 
    ID="alertWindowManager" 
    Skin="Default" 
    AutoSize="true" 
    Animation="None" />

Themes and Demos

There are also plenty of pretty cool demos of all the controls that telerik have created:

http://demos.telerik.com/aspnet-ajax/window/examples/windowmanager/defaultcs.aspx

Thursday, April 15, 2010

HTML rules for Email clients

The following email clients are generally what need to be supported today:
  • Outlook 2003
  • Outlook 2007
  • Outlook 2010
  • Hotmail webmail
  • Yahoo webmail
  • Gmail webmail
  • MacMail
  • Lotus Notes
  • Eudora 
Since most email clients still use HTML 1.1 in one way or another, there are severe limitations to the look and feel of your email.

Here is a list of general rules you can remember when trying to create an email template:
  • Remove <style>.</style>
    • NOTE: This is not always the case and <style> is necessary in some specific cases
  • Remove <script>.<script>
  • Remove <noscript>.</noscript>
  • Remove <link>.</link>
  • Change anything with <.*? /> to <.*? > (e.g. <img /> should be <img>)
  • Change <td></td> to <td>&nbsp;</td>
    • NOTE: Please test as outlook might create a bigger gap in place of &nbsp;
  • There should not be spacing in between the following tags: <img.*? ></td> 
  • <img.*? > should have style="display:block"
    • NOTE: Please test as its not always the case
  • <img src="" needs to be an absolute path
  • <img src="" cannot contain the word "banner"(for spam protection!)
    • NOTE: ISP filters and other technology deployed across the internet have complicated rule sets designed to block banners, advertising and all other manner of communication deemed to be unsolicited commercial email. By naming the folder that contains your image "banner" you are increasing the likelihood that your image, if not your entire email will be outright blocked because you've declared it as a banner in so far as a spam filter is concerned.
  • Replace style="width:0" with width="0"
  • Use embedded style="font-family:." or <font face="."></font>
  • Use embedded style="color:." or <font color=".">.</font>
  • Use embedded style="font-size:." instead of <font size=".">.</font>
  • Replace style="font-style:italic" with <i>.</i>
  • Replace style="font-weight:bold" with <strong>.</strong>
  • Do not use style="padding:[0]"
  • Do not use style="margin:[0]"
  • Replace style="float:[0]" with <table align="[0]"><tr><td>[content here]</td></tr></table>
  • Replace <style> and <link> and replace all class attributes (class="") with corresponding simple class styles (.className)
  • Replace <style> and <link> and add all id attributes with corresponding simple id styles (#id)
  • Replace <style> and <link> and add all element attributes with corresponding simple element styles (elementTag) 
 Most of these can be created with an application that stream reads the HTML template and replaces them using Regular Expressions.

Thursday, April 8, 2010

Using Selenium

Client Setup


Initially, the developer would need to set up a project within the solution of the application they are working on called [ProjectName].UnitTests.

This project will need the following binary references: - nunit.framework.dll - ThoughtWorks.Selenium.Core.dll



Selenium Client Code


Once this is complete, the developer may create their own test cases from scratch or use the FireFox Plugin "Selenium IDE" to record interactions against a specific URL. (The IDE can be grabbed from the following location: http://selenium-ide.seleniumhq.org/)

The selenium code uses the Nunit framework to create unit tests that can be run either with the nunit standalone application, or via a function call in the application. The code will look similar to the following:

using NUnit.Framework;
using Selenium;
namespace MCN0002.UnitTests
{
    [TextFixture]
    public class PromoBuilder
    {
        private ISelenium selenium;
        private string location;
        [SetUp]
        public void SetupTest()
        {
            selenium = new DefaultSelenium("localhost", 5551,
           "*iexplore", Resources.Url);
            selenium.SetSpeed(Resources.Speed);
            selenium.Start();
        }
        [TearDown]
        public void Teardown()
        {
            try
            {
                Assert.IsFalse(location.Equals(selenium.GetLocation()),
               "Has not redirected to the success page.");
            }
            finally
            {
                selenium.Stop();
            }
        }
        [Test]
        public void DateValidation()
        {
            selenium.Click(
           "//a[@id='ctl00_ContentPlaceHolder1_ctlPromoEditor_btnEdit']/b");
            selenium.WaitForPageToLoad(Resources.PageLoadWaitTimeout);
            selenium.Select(
           "ctl00_ContentPlaceHolder1_ctlPromoEditor_ddlPromoStart_Day", "label=31");
            selenium.Select(
           "ctl00_ContentPlaceHolder1_ctlPromoEditor_ddlPromoStart_Month", "label=11");
            selenium.Click(
           "//a[@id='ctl00_ContentPlaceHolder1_ctlPromoEditor_btnSave']/b");
            location = selenium.GetLocation();
        }
    }
}

Server Setup


In order to run the Selenium Client successfully, the developer will need the server application running on a remote machine or their own local machine. The server application (Selenium Remote Control) is built in java and can be found at the following URL: http://selenium-rc.seleniumhq.org/

Once this is downloaded, and assuming the java runtime is installed on the server, the following batch file can be run to start the server:

java -jar "C:\[Selenium Server Location]\selenium-server.jar" 
-interactive -port 5551

Where the port number is decided by the developer. (By default the port number is 4444, however the Firefox Selenium IDE plugin has already taken that)

Recommendations


Page Load timing


Any page load actions (i.e. Click of a button that postbacks, link etc.) must precede the following line of code:

selenium.WaitForPageToLoad("30000");

Where the parameter is the number of miliseconds the process will timeout on while waiting for the page to load.

The reason for this is that the timing of any page load may be affected by many factors which include:
  • the amount of memory on the developer's machine which may take time to open the page using selenium
  • the website being tested is on a slow server
The above line of code will guarantee that if the next action is to check a checkbox, that checkbox will be found on the loaded page. This means that the developer could set the interval speed to as fast as they require.

Checking Error Messages


A common use of testing correct page behavior (especially for forms submission) requires testing whether appropriate error messages get displayed correctly or not. The problem is, however, that a validator on a form is displayed by javascript, which ultimately means that the error message is always on the web page even if it is visible or not. (i.e. the error message will not be an empty string if the validator is hidden).

Moreover, selenium doesnt read attributes for styling (i.e. display:none or visibility:visible).

The solution to this is to check the following:

selenium.GetElementHeight("countryValidator");

If this returns 0 then the error is not displayed, otherwise it is displayed.

Get Attribute


In order to get an attribute of an exact control, the HTML must be interrogated. This interogation is similar to XPaths for XML. The below code gets the "src" attribute of an "img" element that has an attribute "id" of value "imgCheckTraction".
selenium.GetAttribute("//img[@id='imgCheckTraction']@src");

Test Data


Developers should always have a list of testable data that will always be the same no matter how many times you run the unit tests. Any time there is an alteration on the data for validation testing, the data should always be reverted to its original state. This will allow developer to create a new unit test assuming the test data is the original data that was initialized.