Categories
Web Development

Charles in Charge: Actual Mobile Testing with Charles Proxy

There are several decent mobile testing services out there. One that I’ve used significantly is Browserstack, which indeed is pretty good. Still, in my experience, nothing beats testing your site on an actual mobile device.

Further, though anyone with an internet connection can access a public site on their phone, if you have to access something on your computer or Sandbox/UAT server that’s available only by VPN connection, well… you’re up the proverbial creek. Or so you thought…

Accessing sites on your mobile device and through your computer’s internet connection is  made possible by the plethora of HTTP Proxy tools that are out there. But my favorite is Charles Proxy. They offer a persistent free trial version that runs for 15 minutes at a time (after which you’ll just need to restart it), so there’s no reason not to try. Download it for now, and if you like it and want to feed some hungry developers: buy it!

A few notes before we get started:

  • This tutorial is written for connecting to a Mac computer with an iPhone, but as a former Windows/Android man in my earlier life, the steps are for the most part the same.
  • Both your computer and mobile device must be connected to the same WiFi network. I would strongly advise that this network be a secured private one as we’ll temporarily opening up your machine for other devices to connect.
  • When finished testing, be sure to reset your phone’s proxy configuration back to “Off”. If you don’t, your phone won’t have any WiFi connection once Charles has been turned off, and you’ll be left wondering why the heck your phone won’t let you watch that cat video.
  • In the steps below, I am accessing a local site on my computer, which involves the additional step of configuring Apache to actually serve the page. That’s a separate tutorial for another time, but if you’re interested you can check out this tutorial which was how I learned to do that.

OK, let’s get started…

So let’s say you have this Sweet, Sweet Local Site (or something behind your Network Firewall). In either case, you can’t access it on your phone. In order to do so, you’ll need to enable Transparent HTTP proxying on your computer.

Start by opening Charles Proxy, select Proxy > Proxy Settings from the menu.
step-2

This will open up a window with a few panels.  In the first panel labeled “HTTP Proxy”, make a note of the Port number (which should be 8888), and check the box underneath which says “Enable transparent HTTP proxying”. This will basically allow devices connected to the network to connect to your machine via the aforementioned port. Again, warning that you should only be doing this on your home or privately secured network. Click “OK”.

step-3

Your Mac should now be open for your iPhone to connect.

Next, we’ll need your Mac’s network IP. For that we’ll use your terminal and grep. Open up your terminal and run the command: ifconfig | grep "inet". Basically what we’re doing here is searching through the network info dumped by the command ifconfig to find the IP address of your Mac. This value should be indicated by the keyword ‘inet’.

step-1

Grab your iPhone and open up Settings > Wi-Fi. To the far right of the currently selected network, touch the “i” icon to bring up information on the network.

step-4

Scroll down to the HTTP Proxy section, which should have a Configure Proxy option set to “Off”. Press that section and select Manual.

step-5step-6

This will bring up a section where you can enter the Server and Port that you want to proxy through. Enter the IP address and port number mentioned above for the values of Server and Port, respectively.

step-7

If you now try and access your site (or any website, for that matter) via your phone, Charles should now warn you via popup that a device is wishing to connect.

step-8

Click “Allow”. If everything went well, your iPhone should now be able to view the internet through your Mac’s network connection, and you can access Local and Fire-walled sites through your iPhone!

step-9

You can now test away! Just another reminder to reset your phone’s Proxy Configuration to “Off” when you’re done!

Happy testing!

 

Categories
React Web Development

Final onDatesChange with React-Dates

React-Dates is a pretty awesome date-picker library for React built by the developers over at Air BNB. It works well and it’s fairly customizable, so I recommend you check it out if you’re looking for a React datepicker.

Our Desired Functionality:
One issue we encountered – or rather desired functionality that wasn’t baked in and was a little tricky to get just right – was what we called “Final onChange.” Basically, we wanted to fire our onChange event handler only when the user was done interacting with the calendar. This could be when the user finished selecting a range of dates, or when default dates existed and the user selected a new valid startDate before clicking away. This functionality had been requested on their GitHub issues page, but in the end it was determined the logic was more appropriate for the parent component. So we set about figuring out how to build it there.

Our Original Implementation:

class DateRangeInput extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            startDate: null,
            endDate: null,
            focusedInput: null,
        };

        this.valuesDirty = false;
    }

    handleDatesChange = ({ startDate, endDate }) => {
        if (!startDate.isSame(this.state.startDate)) {
            this.valuesDirty = true;
        }
        this.setState({ startDate, endDate });
        if (this.props.onChange && endDate && !endDate.isSame(this.state.endDate)) {
            this.props.onChange({ startDate, endDate });
        }
    };

    handleFocusChange = focusedInput => {
        this.setState({ focusedInput: focusedInput });
        if (!focusedInput && this.valuesDirty && this.props.onChange) {
            this.valuesDirty = false;
            this.props.onChange({ startDate: this.state.startDate, endDate: this.state.endDate });
        }
    };

    render() { /* DateRangePicker here */ }
}

Using momentjs’s isSame method, we would fire the onChange handler if the endDate had changed, or if the startDate had changed and the user navigated away from the calendar. This allowed us to fire onChange when the user had selected a start date and navigated away from the calendar. However it introduced a problem: any other activity resulted in two onChange invocations – one when the start date was selected, the second when the end date was selected.

Attempting to rectify this issue was a little tricky for a couple reasons. First, because handleDatesChange is actually invoked after handleFocusChange. Second, because attempting to access values from state (in this case, startDate and endDate) isn’t a good idea because as we all know: setState is an asynchronous call. Accessing values from state randomly could be subject to a race condition.

Our Solution:

// handle onChange here to ensure state values are current, as setState is asynchronous
afterStateChange = () => {
    let { startDate, endDate, focusedInput } = this.state;

    // fire onChange if either date has changed and calendar has closed (whether automatic or click away)
    if (!focusedInput && this.valuesDirty) {
        this.valuesDirty = false;
        this.props.onChange && this.props.onChange({ startDate: startDate, endDate: endDate });
    }
}

handleDatesChange = ({ startDate, endDate }) => {
    // check if either date has actually changed
    if (startDate && !startDate.isSame(this.state.startDate)) {
        this.valuesDirty = true;
    }
    if (endDate && !endDate.isSame(this.state.endDate)) {
        this.valuesDirty = true;
    }

    this.setState({ startDate, endDate }, this.afterStateChange);
};

handleFocusChange = focusedInput => {
    this.setState({ focusedInput: focusedInput }, this.afterStateChange);
};

What worked for us in the end was first to move all of our logic to a common afterStateChange handler. This ensured the state values we were using would be current. Next we added a valuesDirty check for the endDate (as we had for the startDate) to indicate whether either of the values had changed. And finally, whenever the state was changed, we’d fire our onChange handler only when two conditions were met: (1) when focusedInput was null (i.e. the user had finished selecting a date range or clicked away) and (2) when either of the dates had changed. Easy peasy – just not immediately intuitive!

Hope that helps anyone out there who’s using React Dates and is looking for that extra event!

Categories
Blog U.S. News & World Report Web Development

1472 Days

It’s been a while since I’ve posted anything. 1472 days, to be exact.

Gosh, I was just a newbie at U.S. News & World Report. So much has happened in that time…

Four years.
Three redesigns.
Two bosses.
One (old and outdated) WordPress site.

Oh, and I got married too. That’s kinda big, I’d be remiss if I didn’t mention that.

So my goal is to try and post something weekly. Probably on Fridays. Preferably related to software engineering. Ideally I’ll learn something along the way. And hopefully, someone else will too. That’s probably worth it, right?

As I’ve heard several people say (but most recently Gregg Hurwitz): “You can’t edit a blank page.” So here goes…

Categories
Blog Web Design Web Development

star dot ico

It’s a tiny, seemingly insignificant, sixteen by sixteen pixel image.

But let’s be honest: it’s the first thing site visitors will notice when your site loads, and the only thing that will differentiate you from pretty much every other Bluehost WordPress site out there. And with how so very simple it is to change, let’s get a new favicon up there, shall we?

For those of you who don’t know what I’m talking about, a “favicon” is that square image thingy you notice in the left-hand corner of your browser tab when you visit a site. Standards provide you with the ability to define an individual one for your own site – but if you don’t, a default one will be used. The following steps are for this site (which is WordPress), but it should be easy enough to replicate for all. It’s a simple as:

  1. Using an image editor (cheap, Windows junkie I am, I use GIMP), create an image 64px x 64px.
  2. Design your image, but remember it’s going to have to look great as 16px x 16px. Less it more. Mine is the letter “b”. I am also not a designer.
  3. Scale the image to 16px by 16px.
  4. Save or export your image as a “favicon.ico”. If that extension is not possible with your image editor, you can either (a) get a plugin, or (b) save it as a GIF, JPG or PNG and Google any number of favicon generators out there… those can be hit or miss though.
  5. Upload the “favicon.ico” image to your site. Often, this will be the root directory. But in my case, WordPress was looking for the image elsewhere based on a link tag with the attribute of “shortcut icon”. In that case, I’d rename the existing image to archive it, and upload your new image there.
  6. Ensure the aforementioned link tag is in fact pointing to your new image. If the tag does not exist, it’s not a terrible idea to add it to the <head> block: <link rel="shortcut icon" href="favicon.ico" />
  7. You may need to flush your browser’s cache in order to get it to show up properly.

And you’re done! Now was worth sixty seconds of your time, wasn’t it?