Showing posts with label website. Show all posts
Showing posts with label website. Show all posts

IIS 8 Web Site in Windows 8 externally accessible to the World

Today I needed to allow a per to access an application that’s under development. Instead of buying a cheap ASP.NET hosting account I decided to host the app on my local IIS 8 server. The process to get this configured and working was somewhat exciting since I learned new things along the way.

I’ll show in this post the steps I followed to have this working as expected…

My setup:

  • Windows 8 running inside a virtual machine in Parallels 8 with IP address 192.168.1.107;
  • ASP.NET MVC 4 app deployed in the Default Web Site in IIS 8 that is configured to accept incoming connections in the standard port 80;
  • Linksys WAG200G router/modem connected to the outside/external World.

Steps to follow:
1 - Go to the router’s management interface. In my case it’s located in the address 192.168.1.1.

2 - You’ll need to set a port forwarding configuration. In my case it’s located in Applications & Gaming / Single Port Forwarding. It’ll vary slightly depending on your router vendor and model.

Application: HTTP
External Port: 80
Internal Port: 80
Protocol: TCP
IP Address: 192.168.1.107 (your Windows/IIS machine IP address)
Enabled: True (checked)

Linksys WAG200G Single Port Forwarding configurationFigure 1 - Linksys WAG200G Single Port Forwarding configuration

Make sure to hit the Save Settings button way bellow the page.

3 - Go to Windows 8 Control Panel / System and Security / Windows Firewall / Turn Windows Firewall on or off.
Turn off Windows Firewall for Private Networks.

Turning off Windows 8 Firewall for Private NetworksFigure 2 - Turning off Windows 8 Firewall for Private Networks

4 - Take note of your internet IP address. You can see it in the router’s status page. In my case it’s located in Status / Gateway. Again where you’ll find this info will vary depending on your router vendor.

Taking note of the internet/Gateway IP that uniquely identifies the machine on the internetFigure 3 - Taking note of the internet/Gateway IP that uniquely identifies the machine on the internet

You can also see your current IP Address using Gmail’s Last Account Activity report if you happen to have a Gmail account of course.

5 - Open a browser window and type your internet Gateway IP address taken in step 4. You should be presented with the beautiful IIS 8 default web page if you have no app deployed in the Default Web Site; otherwise you should see your app’s default page/login view.

IIS 8 Default Web Site pageFigure 4 - IIS 8 Default Web Site page

That’s it! Now the web site/app is available externally to any user in any part of the WORLD directly from my development machine.

Anytime I want I can hit Publish from within Visual Studio 2012 and deploy directly to the local IIS 8 server. The user that knows my IP address can then see my ongoing work remotely and free of charge for now.

Note 1
I do not have a static IP address, that is, my ISP here in Brazil (Oi Velox) gives me a dynamic IP address. This means that if there’s a power outage or if the router resets for whatever reason I’ll get a different address – it’s really important to know about this. To overcome such limitation there are some services that can help. One of them is No-IP. It basically allows you to access your computer by a hostname instead of an IP address by using dynamic DNS. They have a free utility app that runs in the background and that automatically syncs your current dynamic IP address with your custom hostname defined in No-IP service.

Excerpts from No-IP site:

What is a hostname?
A hostname is a name given to a computer to make connecting to it easier. Instead of typing out a long IP address you can enter the hostname followed by the domain name, such as myhostname.no-ip.com.

What is dynamic DNS?
Dynamic DNS makes it possible to connect to computers with dynamic IP addresses without needing to know the actual IP address.

They have a free account available with some limitations but it’s worth trying anyway.

Note 2
If for some reason your ISP blocks the default IIS port 80 (something common – hooray! not in my case today) you can try forwarding from a different external port like 8888 in step 2 above. In this case, you’d have to specify this port address when trying to access your IIS server. For example:

189.xxx.xxx.xxx:8888

where 189.xxx.xxx.xxx is your internet IP address.

Software to automate website screenshot capture

I needed a software that allowed me to capture screenshots of a web application I developed. The software should do it automatically (batch capture). This way it’d save me a lot of time.

How do I used to do that?
I visited each web page I wanted to take a screenshot. It took me about 1 hour to finish the work.

I posted a question at Super User as always: Software to automate website screenshot capture and got an answer suggesting that I use a combination of a URL fetcher + Selenium capability to take screenshots.

Well, I tried Selenium (.NET bindings selenium-dotnet-2.0rc3.zip ) to test its screenshot capture feature but it doesn’t seem to fit the job because it doesn’t allow you to configure screenshot properties as size (height x width). Moreover it doesn’t work well with Ajax (requires you to write a lot of code to check for the existence of Ajax calls, etc). This kills a screenshot that needs everything in place (I mean every DOM object should be part of the screenshot). I tried the 3 drivers available: Internet Explorer, Firefox and Chrome. Screenshots taken with Internet Explorer driver were close to what I expected.

This is a sample code I used based on the code taken from here:

using System;
using System.Drawing.Imaging;
using System.Text;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.IE;
using OpenQA.Selenium.Support.UI;

namespace SeleniumTest
{
    [TestFixture]
    public class SeleniumExample
    {
        private FirefoxDriver firefoxDriver;
    
        #region Setup

        [SetUp]
        public void Setup()
        {
            firefoxDriver = new FirefoxDriver();
        }

        #endregion

        #region Tests

        [Test]
        public void DisplayReport()
        {
            // Navigate
            firefoxDriver.Navigate().GoToUrl("http://localhost/FitnessCenter/Report/TotalPaymentsByPeriod");

            IWebElement startDate = firefoxDriver.FindElement(By.Name("StartDate"));
            
            startDate.Clear();
            startDate.SendKeys("January 2011");

            IWebElement generate = firefoxDriver.FindElement(By.Id("Generate"));
            generate.Click();

            var wait = new WebDriverWait(firefoxDriver, TimeSpan.FromSeconds(5));
            wait.Until(driver => driver.FindElement(By.Id("Map")));

            SaveScreenShot(firefoxDriver.Title);
        }

        /// <summary>
        /// Saves a screenshot of the current error page
        /// </summary>
        public void SaveScreenShot(string fileName)
        {
            // Get the screenshot
            Screenshot screenshot = firefoxDriver.GetScreenshot();

            // Build up our filename
            StringBuilder filename = new StringBuilder(fileName);
            filename.Append("-");
            filename.Append(DateTime.Now.ToString("yyyy-MM-dd HH_mm_ss"));
            filename.Append(".png");

            // Save the image
            screenshot.SaveAsFile(filename.ToString(), ImageFormat.Png);
        }

        #endregion

        #region TearDown

        [TearDown]
        public void FixtureTearDown()
        {
            if (firefoxDriver != null) firefoxDriver.Close();
        }

        #endregion
    }
}

Indeed, Selenium is powerful for what it does, that is, helping you automate browser interactions while you test your code. It even allows you to take a screenshot let’s say when something goes wrong (a test fail for example). That’s great and that’s what it does best. It’s a choice for every operating system since it’s an API that can be programmed against.

Paparazzi! beautiful application iconWhat I needed was something more specialized to take screenshots. A software that allows me to configure screenshot properties. The good news is that I managed to find such piece of software and it’s called Paparazzi! - a very suggestive name by the way. One drawback is that it’s only available for Mac OS. As one would expect, it uses Safari browser engine behind the curtains to capture the screenshots. Paparazzi! has minor bugs but it gets the job done. It doesn’t have documentation. I had a hard time trying to make it work. It has batch capture capability but no docs explaining how to do it. So I hope this post will shed some light…

The following lines describe what I did to achieve my objective with Paparazzi!:

1 - Created a list of URLs I’d like to take screenshots of. Like this (one URL per line):

http://192.168.1.106/FitnessCenter/Account/ChangeCulture?lang=en&returnUrl=%2FFitnessCenter%2F
http://192.168.1.106/FitnessCenter/Student
http://192.168.1.106/FitnessCenter/Student/Create
http://192.168.1.106/FitnessCenter/Student/Edit/79
http://192.168.1.106/FitnessCenter/Student/Details/79
http://192.168.1.106/FitnessCenter/Student/Delete/79
http://192.168.1.106/FitnessCenter/Anamnesis
http://192.168.1.106/FitnessCenter/Anamnesis/Create
http://192.168.1.106/FitnessCenter/Anamnesis/Edit/79
http://192.168.1.106/FitnessCenter/Anamnesis/Details/79

.
.
.

2 - Open Paparazzi! and click the Window menu => Batch capture (really difficult to find this option Disappointed smile ):

Paparazzi! difficult to find Batch Capture menu optionPicture 1 - Paparazzi! difficult to find Batch Capture menu option

3 - Drag and drop a text file .txt (the file that contains the URLs) to the Batch Capture window:

Paparazzi! Batch Capture window surfacePicture 2 - Paparazzi! Batch Capture window surface

Here is where I think I found a limitation and it’s by design. This should definitely not happen IMHO. If you try to add a file clicking on ( + button), Paparazzi won’t let you select a text file. The only way I got it working was selecting the .txt file and then drag and dropping the file to the Batch Capture window.

4 - Configure screenshot properties by clicking the list button (see mouse cursor above it):

Paparazzi! screenshot process basic configurationsPicture 3 - Paparazzi! screenshot process basic configurations

You can define the screenshot size. There are pre-defined values for standard screen resolutions. It allows you to define new presets.

You can also delay the capture to wait the page finish loading, etc.

There are a set of configurations available related to the batch capture functionality. To access these configurations, go to Paparazzi! menu and select Preferences:

Paparazzi! Preferences… menu optionPicture 4 - Paparazzi! Preferences… menu option

The first configuration worth mentioning the Default Filename Format available in the General section:

Paparazzi! General preferences sectionPicture 5 - Paparazzi! General preferences section

Above I’m defining this format:

%t = page title
%Y = year
%m = month
%d = day
%H = hour
%M = minute
%S = second

The example in the picture is pretty clear… Smile

Another set of configurations is available in the Batch capture section:

Paparazzi! Batch Capture preferences sectionPicture 6 - Paparazzi! Batch Capture preferences section

Here you can choose where to save the screenshots as well as the type of the images.

After configuring the batch capture session, it’s the gran finale time...

5 - Click the Play button, go take a coffee and relax while the computer does the job for you Fingers crossed.

Paparazzi! Batch Capture in actionPicture 7 - Paparazzi! Batch Capture in action

Hope you have found this post interesting and that it’s useful to help in documenting a little bit of this small but really powerful application.

Pointing up Now I get all the screenshots in less than 1 minute!

References
Paparazzi!
http://derailer.org/paparazzi/