ServiceNow Istanbul – What’s New?

If it’s not obvious from my most recent content, I’ve been spending the bulk of my time in ServiceNow.  For those of you who don’t know, ServiceNow is an enterprise application platform that is commonly used for its flagship ITSM/ITIL application.  While IT Service Management is its main use, the platform allows business developers to quickly deploy integrations and services in a cloud and mobile ready state with less effort than building from bare metal.

One of the most recent announcements is for the latest major release, called Istanbul.  This latest version passed into general availability this month and has many exciting new features.  I recently attended a webinar that covered the highlights.  You can find the recorded session here.

Automated Testing – This is the piece that ties back into my most recent series on testing.  The automated testing suite in Istanbul is probably the feature I’m most excited about.  The Automated Testing Feature gives developers a native toolkit for building test suites for both UI and server-side unit testing.  Tests can be organized by feature or combined into multiple testing suites for regression testing for future releases.  I’m a fan!

Debugger ‘2.0’ – One of the challenges on this platform is the debugging implementation.  Often, I find myself avoiding the native debugger in favor of logging by hand or using the browser console to detect issues on the platform.

Istanbul restores a debugger tool that was popular in pre-Geneva releases but was turned off some time ago due to functionality issues.  The updated tool runs in its own window and allows developers to add breakpoints specific to them for working with their code.  This means that developers can simultaneously use the same functions while not stepping on each other’s toes with unwanted test cruft.

HTTP Message Logging – For those of us who work with external integrations involving critical business functions, failed event captures in this space can result in unnecessary impact and reduced confidence in your service delivery strategy.  Adding to this is the possibility of finger-pointing between dev groups and a lot of guesswork in troubleshooting the failure.

Istanbul attempts to help with this by breaking out HTTP message logging out of the box and adding it by default.  This not only helps with visibility and troubleshooting of integration issues in production, but development and testing of new integrations.

Email Unsubscribe – One of the common user complaints that come with new platforms is the volume of email that comes by default.  While the platform already allows users to pick and choose what notifications they want to receive, often there’s a disconnect between the actual notification and the setting users might need to change.

One new feature of Istanbul allows developers to add an Unsubscribe link to notifications they send.  This allows notification recipients to opt out of that traffic with a single click in the moment rather than forcing them to log into their user configuration and then remember which notification they’re stopping.

Email WYSIWYG Editor – User experience is often an afterthought or even forgotten when working with a business application.  Part of improving that experience involves delivering content in a more polished manner, rather than just spamming people with walls of text.

While the previous email template editor allowed for markup content, developers were limited to a code only interface, which involves a lot of guesswork in practice.  Istanbul adds a WSYIWYG editor which will allow for quicker delivery of user friendly web-style content in notifications from ServiceNow.

As always, if you have any questions or comments, please feel free to add them here or address them to john@benedettitech.com.

Thanks for looking in!

Reading Summary – 2016

Posting book recommendations seems to be a thing when New Years rolls around.  The last time I posted about books, I put together a list of my favorite recommendations.  This time around, I put together a list of books I read over the past year.

Essential ASP.NET with Examples in C# – A bit obsolete.  Vanilla web forms rather than MVC.  However, I did find some useful nuggets around IIS and ASPX page architecture.  Any of you still involved in IIS hosting or legacy support might find some value.

Wherever You Go, There You Are : Mindfulness Meditation In Everyday Life – In depth overview of mindfulness with various case studies and examples or thought experiments in easily digestible form.  A good read for those seeking the value of being present and deliberate.

Richest Man In Babylon – A book on financial health with guidelines packed into parable form.  It’s mostly common sense stuff and a bit repetitive, but still useful.  ‘The 10% Rule’ was most valuable to me.

Clean Code – A classic book on software quality that easily makes most developer’s reading lists.  Some of the most valuable pieces for me were:

Focusing on indentation – The idea that if your indentation is sloppy, you should focus on that before anything else

Boy Scout Rule – Always leaving code better than you found it

Test Driven Development – The principle that tests are always closer to the truth about code’s purpose than comments or documentation

Leviathan Wakes – The novels on which the series The Expanse is based on – I honestly haven’t had a book grab my attention like this in a long time and would highly recommend it to any sci-fi fan. The setting is gritty with enough everyday human concerns to be a believable future state while still having stakes and scope worthy of space opera.

Waking Up – Interesting premises on the nature of the mind, the concepts of self and better living through meditation.

The Analects – A collection of Confuscious’ sayings and one of the core works of Confuscianism, the main idea of which is virtuous living and self development according to The Way.  It’s a decent read but I get the feeling that The Way being discussed is very specific to the author and his students (Upper Class Chinese Nobility)  For the modern reader, The Way may be more subjective but the call to action is not.

The Death of Common Sense – I heard a rumor that this book was an inspiration for the character of Hank Hill (King of the Hill), so I had to take a look.  An indictment of following the letter of the law at the expense of the spirit.

Meditations –  A collection of the writings of Marcus Aurelius and one of the core works of Stoicism.  I’d compare this to the Analects as far as the need for context.  But again, the call to action is definitely not subjective.

Not a long list, to be sure.   This year I’m hoping to double it, but hopefully not just for the sake of quantity.  I think my pile of books to read actually grew more this year.

I’d love to hear any feedback on this list and invite you to share your own reviews or recommendations.  As always, if you have any questions or comments, please feel free to add them here or address them to john@benedettitech.com.

 

Thanks for looking in!

UI Unit Testing with Selenium – Part 4 – Selenium Server

 

Last time, I went over more advanced uses of Webdriver as well as putting together a framework of shared methods which can be hooked up to unit tests. For this last post, I’ll be standing up an instance of Selenium Server on Amazon Web Services and refactoring the test framework to point to that instance for testing.

What is Selenium Server?

Selenium Server is basically a hosted service that can accept and run Selenium tests independent of the actual testing client.  This allows for shared infrastructure that can be accessed by various clients without repeating the provisioning and setup of WebDriver files and other libraries.

For the provisioning of Selenium Server, I’ve decided to try out Amazon Web Services Elastic Computing service.  If you’re curious about AWS and want to take it for a spin, you can sign up for a free trial period that’s currently 1 year!  Information on EC2 and a link to sign up for the free trial is available at this link.

Standing up Selenium Server on AWS EC2

So first, I need a host.  After signing up for my free trial, provisioning an EC2 virtual machine using Windows Server only took a few minutes.

Then, I was able to copy over the Selenium Server JAR file and the Chrome WebDriver.exe.  Both of these can be found at the Selenium downloads page here.

Additionally, since the service is a Java Virtual Machine, I needed to install a Java Runtime Environment located here.

With my host, runtime and libraries in place, it’s time to start the service itself.  This involves a simple command line statement.  Elements show the location of the Chrome WebDriver on the EC2 host and I’ve also created a log file to keep track of any activity.

java -jar -Dwebdriver.chrome.driver=C:\ChromeWebDriver\chromedriver.exe C:\SeleniumServer\selenium-server-standalone-3.0.1.jar -log “C:\\SeleniumServer\SeleniumLog.txt” 

Refactoring the test project

Once the host is available, it’s just a matter of starting the host and telling the framework where it’s located.  This requires the download of an additional NuGet package called OpenQA.Selenium.Remote which gives you access to the RemoteWebDriver class.  Then I updated my Login and InternalLogin methods to use that as the framework’s IWebDriver object instead of the local one.

With these changes in place, my tests passed with flying colors.  While I chose not to run tests in anything but Chrome this time around, adding additional platforms for testing is as easy as adding the drivers to Selenium Server and then updating the DesiredCapabilities argument of the RemoteWebDriver object.

To wrap it all up, I committed my refactor to my SeleniumFramework repo on GitHub.  Please feel free to look at the updated version and pass along any feedback you might have.

Again, I hadn’t expected this series to take as long as it did, but it feels good to bring it to a close with some working code to show for it.  As always, if you have any questions or comments, please feel free to add them here or address them to john@benedettitech.com.

Thanks for looking in!

UI Unit Testing with Selenium – Part 3 – Advanced Webdriver & A Real World Example

Last time, I got into the basics of Webdriver and put together a couple of tests against ServiceNow.  For this post, I’m going to take a look at more advanced uses of Webdriver as well as putting together a framework of shared methods which can be hooked up to unit tests.  This involved going a little off script for the original course, but I think this series might be better served demonstrating application of the actual content rather than repeating it.

The goals that I have for this post will involve creating a new Solution with a Unit Test project as well as a Selenium framework class that can be reused within multiple tests.  Again, I’ll be testing against my private dev instance of ServiceNow, but I think it will be readily apparent how the framework could be extended as needed for other web frameworks.

I began by first creating a new testing project in Visual Studio, called SeleniumFrameworkTests.  Then I added the following tests based on the activities I demonstrated in the previous post.

LoginAsUser
LoginAsSuperUser
CreateIncidentAsUser
CreateIncidentAsSuperUser

I knew I’d want each test to be completely abstracted from the plumbing of ServiceNow, so I kept each test down to three arguments: environment, username and password.  The environment would hold the URL of the instance we’re connecting to.  And the username and password would contain those values for the account role needed to perform the tasks.  Lastly, I created an app.config file to hold the values.

testproject

Next, I created the main framework class called SeleniumFramework.  This framework class would need to include the Selenium and Selenium.Support packages from NuGet.  With that in place, I created the general Login method which accepts the environment, username and password arguments.  Then I copied the login steps from the previous post.  This allowed both the LoginAsUser and LoginAsSuperUser tests to pass.

loginmethod

The CreateIncident methods proved to be a little trickier.  First, each would require it’s own IWebDriver object with a valid login in order to proceed.  It made more sense to create a private method that returns an IWebDriver object for use by the CreateIncident methods.

privatelogin

With that in place, I copied in the CreateIncident steps from the previous post. The CreateIncidentAsUser test then passed but the SuperUser role has a different interface than the base User.  To get that test to pass, I had to create a separate method and tweak the UI names as needed for the test to then pass.

createincident

To wrap it all up, I created a new repo on Github called SeleniumFramework. Please feel free to take it for a spin yourself.   All you’ll need is a demo instance of ServiceNow as well as a copy of Visual Studio Community, both of which are free!

I know this series has taken much longer than I expected. However, I plan to close it out next time with an implementation of Selenium Server, most likely using the above testing project.

As always, if you have any questions or comments, please feel free to add them here or address them to john@benedettitech.com.

Thanks for looking in!

UI Unit Testing with Selenium – Part 2 – Webdriver Basics

Last time, I did a quick run-through of Selenium IDE for Firefox and got acquainted with the interface and commands associated with Selenium.  This time, I’m diving more into the meat of the framework and using Webdriver.

Webdriver is an API for that can be used by various languages (C#, Java, Python, & Ruby are some examples) that allows your tests to be maintained and run directly from code rather than using a recorder.  This allows us to take a more programmatical approach to testing rather than relying on the recorder exclusively.

We will be using Visual Studio for this example.  Firefox is supported right out of the box, but IE and Chrome require a special binary to be staged locally in order for those browsers to be used with Selenium.  This (and others) can be located via links at SeleniumHQ.

Since Chrome is my own preferred browser, I’m glad to move away from Firefox and experiment with something a bit more familiar.  I decided to start with rerunning the test that I created using Selenium IDE previously, then build on that a bit.

One feature that I didn’t mention about Selenium IDE, is the export function.  This creates source code in your chosen framework (C#, Java, etc.) from the Selenium markup code created by the recorder.

seleniumexport

One cool thing about the export is that it intersperses the markup within your code as comments.  This can be very useful when retracing what was done in a recording or for general documentation.

First off, I created a C# console project and installed the Selenium Webdriver plugin from NuGet.  With that in place, I’ve added the export from my previous post to a new project to test with Chrome.  My code is below:

using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace WebDriverDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            IWebDriver driver = new ChromeDriver(@”C:\Libraries\”);
            driver.Navigate().GoToUrl(“https://dev20556.service-now.com/navpage.do”);
            driver.SwitchTo().Frame(“gsft_main”);
            driver.FindElement(By.Name(“user_name”)).Click();
            driver.FindElement(By.Id(“user_name”)).Clear();
            driver.FindElement(By.Id(“user_name”)).SendKeys(“USERNAMEGOESHERE”);
            driver.FindElement(By.Id(“user_password”)).Clear();
            driver.FindElement(By.Id(“user_password”)).SendKeys(“PASSWORDGOESHERE”);
            driver.FindElement(By.Id(“sysverb_login”)).Click();
        }
    }
}

This sample using the export from my previous post results in a successful login.  Now to build on it a little bit and create a test Incident:

            driver.FindElement(By.LinkText(“Incidents”)).Click();
            driver.SwitchTo().Frame(“gsft_main”);
            driver.FindElement(By.Id(“new_incident”)).Click();
            SelectElement urgency = new SelectElement(driver.FindElement(By.Name(“IO:5a33d0ef0a0a0b9b007b906f6c589c57”)));
            urgency.SelectByText(“1 – High”);
          driver.FindElement(By.Name(“IO:3f272c500a0a0b990059c24380a2bc02”)).SendKeys(“Creating a test incident.”);

            driver.FindElement(By.Name(“submit_button”)).Click();

Just adding these few extra lines results in a repeatable New Incident test.

incidentsuccess

It’s easy to start to see how this framework can be used to build a library of repeatable tests to automate QA and regression testing.

Link to the Full .NET API : http://seleniumhq.github.io/selenium/docs/api/dotnet/

As I continue to progress through the Pluralsight course, my next post should cover advanced WebDriver concepts and possibly Selenium Server.

As always, if you have any questions or comments, please feel free to add them here or address them to john@benedettitech.com.

Thanks for looking in!

UI Unit Testing with Selenium – Part 1


So, I’m making it through the Selenium Pluralsight course slowly but surely and I’m learning quite a bit so far.

The first part covers a browser plug-in called Selenium IDE.  Available only for Firefox, it’s essentially a session recording tool,  It records what we do in the browser then parses those into commands and then can be played back to act as tests.  To take this out for a spin, I went ahead and installed the plug-in and watched the demo on the course.  Now, we’ll need to find something suitable to test it on.

selenium

There’s a SaaS platform called ServiceNow that I’ve been spending a great deal of time in this year.  Automating testing against this platform from a central host is one of my goals for this experiment.  To test this out, I’ve created a test instance of ServiceNow and a test user.  Also, I’ve installed the Selenium IDE on Firefox so that I can record my session in the platform.

My demo is basically automating a login for my test user.  First I’ll need to create a fresh test case in Selenium.

newtest

Then, I’ll record the steps to the login to get a complete test.

finishedtest

Then I’ll run the test and see if it logs me into the system, which it does.

success

This is just scratching the surface of Selenium and I have more modules in the course to cover.  Next post, I’ll have some additional content from the next module (Selenium Web Driver) and possibly a little more.

As always, if you have any questions or comments, please feel free to add them here or address them to john@benedettitech.com.

Thanks for looking in!

UI Unit Testing with Selenium – An Experiment

It’s been a while since I’ve posted.  Part writers block and part outside obligations.  I know you’ve all been despondent and lost in the meantime.  Sorry about that. 🙂

Something that’s a recurring puzzle for me is adapting unit testing to MVC and SaaS solutions.   The challenges from my point of view are that MVC implies a lot of its functionality.  For example, things in MVC behave in very specific manners based on where they’re located or what they’re named.  Also, MVC classes (models) generally don’t have or need default constructors, so a traditional approach of instantiating a class an running business logic is insufficient.

Then, for SaaS solutions, you may not have sufficient access to the plumbing to build your tests directly, so you’re stuck automating a session through the SaaS provider’s interface and (hopefully) capturing the results that you need.  An approach to MVC might look very similar.

Enter Selenium

Either my Google-fu is weak in this space or there aren’t a lot of options for automating tests in this manner.  One framework that gets a lot of mentions is Selenium, so I’m going to take a stab at it.   I’ve found a few good blog resources but also remember that John Sonmez did a Pluralsight course that seems to be right up my alley.

My plan for this week is to watch the course and play around with the framework against a solution or two, then post about the results.  If the path seems promising, I’ll follow up with some additional content.

As always, if you have any questions or comments, please feel free to add them here or address them to john@benedettitech.com.

Thanks for looking in!

Adding Widgets to WordPress

I wanted to flesh out the blog itself a little bit and experiment with WordPress. So, I decided to add some Widgets to the sidebar. These are configurable items that you can arrange alongside other WordPress content like menu and category links. They can be based on plug-ins or can be iFrames or just straight HTML so I’ve added a few examples. Once created, they can be arranged or reordered at will or shown/hidden based on certain conditions such as page or WordPress user properties.

ArrangeWidgets

First off, I wanted to brand the blog using the logo from Simple Programmer that I earned by completing the course that launched this blog in the first place. This is a simple hyperlink tag sourcing an image file as the element. To add this, I created a Text widget which allows you to add arbitrary text or html.

CreateText

spwidget

Next, I wanted to add a link back to the Github repository I created for a previous entry here. I accomplished this by installing a plug-in called WP Github from the WordPress marketplace. This allows you to add widgets for various GitHub categories such as repos, commits or issues. I’ve added the top level profile widget for now, but you can insert various other widgets specifically for repos or commit history.

wpgithub

Just for fun, I included a link to my Myers-Briggs personality type from 16 Personalities. This quiz and personality typing has been popular at some of the organizations and businesses I’ve worked with, some even going to far as to require employees to post them beside their nameplates. Adding this involved another Text widget. This one is a simple anchor tag referencing an image from the site and linking back to the 16 Personalities website.

Code:  <a href=”https://www.16personalities.com/intj-personality”><img src=”https://www.16personalities.com/images/types/intj.png”></a>

My last widget is a bit of personal accountability for me. I’ve struggled with weight for most of my life and have been tracking my weight and eating habits at Livestrong. This is a free service and they also provide a code snippet that points back to your progress on their website. This was accomplished by pasting in the code snippet into another Text widget.

lswidget

Pretty straightforward stuff, right? As always, if you have any questions or comments, please feel free to add them here or address them to john@benedettitech.com.

Thanks for looking in!

BenedettiTech’s Reading List

I’ve been seeing quite a few book recommendation lists lately.  So, I decided to throw my own hat into the ring with my own list of book recommendations.

While writing this list, I laid down a few ground rules for myself:

  • Only 1 book per author – I did keep a short list of runners up after the main list.
  • No Fiction – Unless the lesson from the book is singular and embedded, you might have better luck looking for a philosophy book with an explicit lesson and a more thorough explanation.  Lessons from fiction to me are mostly subjective and allegorical so I kept a short list of fiction books that I would recommend to anyone.
  • I have to have read it recently enough that I can summarize the book from memory. – My thoughts are: If I can’t throw together a few sentences about the book from memory, it must not have been that impactful.

The List

The Art of War – Attributed to Sun Tzu & Others. My absolute favorite.  Don’t let the title put you off.  This is as much about preparation and choosing your battles as actual conflict.

The Pragmatic Programmer – Andrew Hunt – Great soft skills title that I recommend to all developers.

 
The War of Art – Steven Pressfield – Not exactly an inversion of the first book on this list.  This title is about focusing on and executing on your goals.  It’s about the importance if action and how to not sit idle.

Soft Skills – John Sonmez – I ordered a copy of this to share with my team at my regular job.  It’s surprisingly broad for a work intended for an IT audience. I could even call it a holistic approach to living life as a developer.

 
The 7 Habits of Highly Effective People –  Stephen R. Covey – A classic on mindful and focused execution.  The themes and habits of this book are taught in grade schools now.

Choose Yourself – James Altucher – This book is about betting on yourself in the face of adversity.

Purple Cow – Seth Godin – This book was required reading for me in college and is about standing out.  In a world full of developers, services and consultants, what makes you stand out?

Getting Things Done – David Allen – A productivity system that is as much about cognitive load and capacity as it is about efficiency.  I use it daily.

The Demon Haunted World – Carl Sagan – A good primer on worldly skepticism and critical thinking from the man himself.

The Art of Deception – Kevin Mitnick – Case studies on social engineering and black hat strategies.  Reinforces the point that people are always the weakest link in IT Security.

Surely You’re Joking, Mr. Feynman! – Richard P. Feynman and Ralph Leighton – A quasi autobiographical collection of memoirs from Dr. Richard Feynman.  Reinforces the idea that its possible to literally change the world while having fun and having a life.

Rich Dad Poor Dad – Robert Kiyosaki – A basic education in money management and asset growth that should be required reading for every student.

So Good They Can’t Ignore You – Cal Newport – Titled with a paraphrased quote from Steve Martin, this is a long form reminder to focus on skill growth in your trade while striving to excel and continuously parlay those skills into more important or valuable roles.

What If? – Randall Munroe – Anyone familiar with the web comic xkcd may already be familiar with this or even own a copy.  An entertaining attempt to answer interesting thought experiments with solid science and fun humor.

This Is How – Augusten Burroughs – A collection of essays that addresses strategies for confronting monumental life events and circumstances that can stop any of our lives in its tracks despite our best laid plans.  Blunt and plainspoken while still being compassionate.

Runners Up

The Warrior Ethos – Another one by Steven Pressfield.  This one is a more general overview of having a code and being worthy of trust.

The Dip – Another one by Seth Godin.  Shares a message with War of Art and Choose Yourself.  The main difference is that this book predicts that there will always be a point in any project or journey where you’ve lost momentum and feel stuck.  This can be both an obstacle or overcome but also an opportunity to stop and ask yourself if the goal is still worth your time.

Pale Blue Dot – Probably a more popular Sagan work than the one I chose.  This one focuses on the imperatives of taking care of our planet and making an investment in a shared future, recognizing that it’s the only one we have (so far) and we’re all in this together.

Fiction

Neuromancer – William Gibson – This is a classic of the cyberpunk genre and is credited with the coining of the term The Matrix for an Internet in the style of shared virtual reality.  Also touches on the concept of the Technological Singularity.

American Gods – Comparative religion and the modern personification of mythological figures is a popular realm for Neil Gaiman.  Expect to hear more about this novel in the coming months as it’s currently being turned into a feature length movie.

The Godfather – Probably the one novel I’d choose to be stranded with on a deserted island.  While most movies based on novels are derided for leaving out key elements, I believe the movie not only honors the source material but also complements it.  If you read it for one reason only, do it for the backstory of Luca Brasi.  You’ll never look at his halting wedding benediction the same way again.

I’m interested in hearing feedback on this list or some additional suggestions of your own.  If you have any questions or comments, please feel free to add them here or address them to john@benedettitech.com.

Thanks for looking in!

GameCareerGuide – Unity Platformer Tutorial

So, in keeping with the C# theme, I decided to take a stab at creating a small project in Unity and publishing it to Azure. To do this, I followed a tutorial provided by GameCareerGuide to create a simple platformer.

What is Unity? Unity is a popular game development platform that is free for individual developers contingent on revenue reaching a certain benchmark. (Currently $100K). You also have the option to buy a Pro subscription for $75 a month. I’m only at a stage where I’m tinkering around with the IDE and learning, so I’m not interested in paying for a sub if it’s not necessary.

unity

What is Game Career Guide?  GameCareerGuide is a site aimed at helping individuals who want to pursue a career in Game Development. There are various news items as well as links to resources and communities to help people launch or grow their careers. I came across the 2014 edition of their publication here and the tutorial I’m using begins on page 36.

gamecareer

Creating this was pretty straight forward. I had a copy of the 5.x version of Unity already installed and went through the steps in the tutorial creating various assets/objects to use in the game. One hurdle I ran into was needing to update the code as one of the base classes it relied on had been deprecated since the release of the guide. I was able to solve it using some simple cut & paste outlined in this article

deprecated

Next, I was having some issues committing the completed project to a Github repository. Something to do with how Github handles line breaks that can cause code corruption in some cases. Fortunately, updating the Github configuration for the new repo did the trick. I was able to use the Github CLI with the assistance of this article here to allow my code to commit. Even with the config change, my code built smoothly so I’m pretty sure there’s no risk.

After that, I created a new Web App node on my Azure account and used FileZilla to load my build via FTP. At first, the game was erroring out in both Firefox and IE so again I had to make a stop at the Googleverse. It seems that the site needed to provide a configuration item to allow the proprietary .unity3d file to download when you load the site. I was able to add the web.config file based on the following article

config

Finally, it was time to test out the game. Quite honestly, I’m a bit overly proud of taking these disparate platforms and making them work together. Plus it’s just neat to get something new to work, even if it’s trivial.

platformer

If you’re curious about the game, you can find it here . The controls are Left and Right Arrow and the spacebar and the object is to reach the yellow ‘exit’ square at which point the level resets. My son suggested that I might add some more levels and make it grow more difficult at each new level. Additionally, if you want to see the source code, you can find the repo on my Github account here.

If any of you are curious about or have used Unity or have any questions or comments, please feel free to add them here or address them to john@benedettitech.com.

Thanks for looking in!