Expected duration
8–10 hours
Deadline
2300 on Lesson 28
Points
75 points

Learning Objectives

  • Create an eXtensible Markup Language (XML) document that is well-formed and valid
  • Create a website that uses HTML and Cascading Style Sheets (CSS)
  • Validate user input using client-side scripting (i.e., JavaScript)
  • Analyze XPath expressions to identify and to resolve failures in automated tests for a website

Help Policy

Authorized Resources
Any, except posted solutions and working together with classmates.
Notes
Never copy another person’s work and submit it as your own.

Do not jointly work on this programming exercise (PEX), but you may ask classmates syntax questions. There are no restrictions regarding discussion of the XPath expressions used in automated tests, including how to interpret these expressions or how to reproduce the test cases manually.

You must document all help received from all sources, including the instructor and instructor-provided course materials (including your textbook). One exception: you do not need to document any resources related to HTML, CSS, or JavaScript syntax unless received from a classmate.

Instructions

Use the provided link (distributed separately – look in Blackboard under “Assignments” for the invitation link) to access the assignment in GitHub Classroom.

This assignment has two parts. The first provides practice with the eXtensible Markup Language (XML). The second covers client-side web technologies, specifically the Hypertext Markup Language (HTML), Cascading Style Sheets (CSS), and JavaScript. Each part is described in turn.

XML

All these files will reside in the src/xml directory of the Git repository.

  1. Create an XML file, schedule.xml, to store your semester’s academic schedule. The root element of this XML document should be schedule.
  2. Include a personal information element, personal, with the following elements: name, squadron, and year.
  3. Detail your schedule in a classes element, which comprises one or more class elements. Each class element must include the following child elements:

    name
    Name of the course
    period
    M1, M2, …, T7
    score
    Current grade in the course

    In addition, each class element must have an id attribute with the course number. For example, the id for this course is “Comp Sci 364” and the content of the name element should be “Databases and Applications”.

An XML Schema Definition (XSD) is included in the repository (src/xml/schedule.xsd). Your XML document must validate against this XSD for complete credit for this portion of the assignment. (Your XML document will be validated automatically when you push changes to GitHub as part of the automated tests.)

HTML, CSS, and JavaScript

All these files will reside in the src/web directory of the Git repository.

This assignment is designed for you to learn and practice how to create web pages with HTML to include submitting data via forms and presenting data via tables, use CSS to control and standardize the presentation of the website, and use JavaScript to validate form data prior to submission.

Requirements

The Cadet Service Learning (CSL) office needs to gather information for its database of volunteers. They would like you to develop an initial website that provides information about the CSL program, lists some of the partner service organizations, and provides a form to collect information about volunteers.

The specific (enumerated) requirements for this project are as follows:

  1. The website shall provide separate pages to describe the CSL program (index.html), list the partner service organizations (partners.html), and gather information from volunteers (volunteer.html).
    1. The description of the CSL program shall include the provided picture (csl-logo.jpg) to add interest to the description. The description shall comprise the following text at a minimum:

      The Cadet Service Learning program is designed to foster and facilitate service learning activities for cadets at the United States Air Force Academy.

    2. The listing of partner service organizations shall include a table with the name, location, and phone number for each of the following organizations:

      Name Location Phone
      Habitat for Humanity 2802 N. Prospect St., Colorado Springs, CO 80907 (719) 475-7800
      Salvation Army Soup Kitchen 908 Yuma St., Colorado Springs, CO 80909 (719) 636-3891
      Big Brothers Big Sisters of Colorado 111 S. Tejon St., Suite 302, Colorado Springs, CO 80903 (719) 633-2443
      Keep Colorado Springs Beautiful Inc. 20 E. Rio Grande St., Colorado Springs, CO 80903 (719) 577-9111

      You may include additional organizations, but these must be listed.

    3. The information gathered for volunteers shall be the first name, last name, email, age, gender, and whether they have access to a car.
      1. The gender input shall be radio buttons with (at least) the values of “male” and “female”.
      2. The carAccess input shall be a checkbox.
    4. The gathered information for volunteers shall be validated against the following criteria with invalid data flagged and the user forced to correct it for successful submission.
      1. First and last names shall include only letters, spaces, and hyphens and each will be no more than 50 characters.
      2. Email addresses shall include only letters, digits, hyphens, underscores, periods, and one (and only one) at sign (“@”) and no more than 50 characters.
      3. Age shall be numeric and in the range of 17 to 29 (inclusive).
    5. Validated information for volunteers shall be passed to the provided demo.php page.
  2. All pages in the website shall have a consistent layout and structure to include on each page:
    1. The site title, “Cadet Service Learning Program”
    2. A page title—“CSL Introduction,” “CSL Service Partners,” and “CSL Volunteer Form” for each respective page
    3. Direct navigation to all other pages
    4. Consistent background color, font, and font color
  3. Two distinct presentation color schemes shall be provided. Include the provided JavaScript file (script.js) so a “toggle button” will appear in the lower right corner of the screen to display the current page in the alternate style.
  4. The website will follow the design quality guidelines specified in the HTML and CSS lesson.
  5. Add additional feature(s) to your website based upon research on W3Schools or seeing how other websites implement cool features (use “View Source” to see the implementation of a page). These features could include cool graphics, interactive features implemented via JavaScript, embedded video, background audio, …. (Note: This is not a “great requirement” as it is very subjective, but it is serving a higher purpose).

Be sure to use the correct input type for gender and car access. While different types may provide comparable functionality, they will not pass the automated tests.

To better understand the requirements for this project, the following use case is provided. It describes a usage scenario for the CSL website to provide a better understanding of “what” is needed.

Cadet Service Learning (CSL) Web Access

Summary
USAFA cadets access the CSL website to learn about the CSL program, determine who the service partners are, and submit their information.
Preconditions
  1. Cadets either know the CSL website URL or are provided a link.
  2. Cadets know their personal information.
Trigger
Cadet opens the CSL website in a browser.
Actors
Cadet who accesses the CSL website and demo.php that responds to submitted cadet information
Scenario
  1. Cadet accesses the CSL website via a browser.
  2. Cadet is immediately able to read about the CSL program.
  3. Cadet navigates to separate page listing service partners.
  4. Cadet accesses the form for providing the requested information.
  5. Cadet enters and submits information that is validated with any errors or omissions highlighted.
  6. Cadet corrects errors and omissions and resubmits.
Alternatives
Cadets can move directly (via one click) between the introduction page, service partner page, and information form page.
Success Condition(s):
Cadet provides validated information that is echoed back to them.
Failure Condition(s):
Cadet is not able to retrieve a copy of their information after form submission.
Exceptions
Cadet information echoed from demo.php will not be within the same layout and navigation structure used by the rest of the site.

Design

The design of the Cadet Service Learning website will be provided as structural design, user interface design, external interface design, and component logic design.

Structural Design

The CSL website consists of three web pages that share a common layout, navigation structure, and presentation format. The three pages are Introduction (index.html), Service Partners (partners.html), and Volunteer Information Form (volunteer.html). They are organized in a linear structure. The Volunteer Information Form page has an external interface to the provided PHP file (demo.php) that will echo back the provided information. Details of this interface are provided later in the design.

User Interface Design

The layout of the pages needs to be consistent and follow proper design quality guidelines. Normally, we would show this layout in the design document. However, for this assignment, we want to give you freedom to specify your own design so we just show a notional layout and leave it to you to customize and tailor.

+--------------------------------------------------------+
|            Cadet Service Learning Program              | <- header, with site
+------------------+------------------+------------------+    title
|    CSL Intro     | Service Partners |  Volunteer Info  | <- navigation bar
+------------------+------------------+------------------+
|                       Page Title                       | <- title of current
|                                                        |    page
|                      Page Content                      |
|                                                        |
+--------------------------------------------------------+

The presentation design is to be based upon a single, common Cascading Style Sheet (CSS) that specifies the background colors, font styles, font colors, font sizes, and other characteristics (as desired) for each type of region (site title, page title, navigation bar, and content area) on the website. There will be two CSS files, each of which provides a significantly different look to the site. These files should be named csl.css and csl-alt.css for the primary and alternative style sheets, respectively. By including the provided JavaScript file (script.js), a “toggle button” will be provided in the lower right corner of the screen to display the current page in the alternate style.

The service partner listings will be implemented with an HTML table with distinct headings (i.e., different from that for the entries).

External Interface Design

The external interface between the volunteer information form and demo.php is provided via a HTTP POST method triggered on the HTML form submit action. The parameters passed with this post are to be named as follows:

  • firstName
  • lastName
  • emailAddress
  • age
  • gender
  • carAccess

The values provided by the POST method for these parameters are echoed back by demo.php via an HTML-formatted response. This page will not be part of the CSL website so the user will need to either click on the link provided on that page to return to the CSL site or use the “Back” button in the browser.

Component Logic Design

The only programming logic implemented for the CSL website is the JavaScript routine to validate the volunteer information form data. This routine will return true if all the form data meets the criteria or false if any information fails validation. That return code will then be used by the browser to determine whether to call demo.php (if result is true) or simply return to the form for corrections (if the result is false).

Function Validate_Info_Form_Data()
  Set errorsWithForm to False
  Check for missing lastName, firstName, email, age
  Check and report character and length errors with lastName
  Check and report character and length errors with firstName
  Check and report character errors with email
  Check and report numeric and range errors with age
  Return errorsWithForm
End Validate_Info_Form_Data

Testing

This section documents how the CSL website will be verified against its stated requirements.

Test Environment

The test environment will be the website and demo.php running under a Linux, Apache, MySQL, PHP (LAMP) stack and the Mozilla Firefox browser used for access (although your site should render on any standard-compliant browser, including Google Chrome, Safari, Internet Explorer, and Microsoft Edge).

For automated tests, the test environment – running on Travis CI – uses PHP’s built-in web server with the Selenium framework for web testing and ChromeDriver for headless execution of the Chromium web browser. This environment should be comparable to serving the website using LAMP and viewing it in Mozilla Firefox.

Test Procedures

The following test procedures will be used to verify each requirement is satisfied.

Test Case Requirement Action Expected Response
1 1 Access the CSL website from the browser Website loads and displays
2 1a Read the content for the description of the CSL program and verify there is a picture Description and image found and determined to be appropriate
3 1b Navigate to the Service Partners page and verify that there is a nicely formatted entry for each partner to include name, location, and phone number Service partner entries are present and complete with appropriate formatting
4 1c Navigate to the Volunteer Information form and verify that there are means to input first name, last name, email, age, gender, and whether they have access to a car Form controls for all data items are present
5 1d Submit Volunteer Information form with missing last name, first name, email, and age All four data items are reported as missing
6 1di Submit Volunteer Information form with a last name that has at least one of each type of valid character and no invalid characters Entered data is accepted and echoed back by demo.php
7 1di Submit Volunteer Information form with a last name that has an invalid character Error is detected and reported with demo.php not called
8 1di Submit Volunteer Information form with last name that is 51 characters long Error is detected and reported with demo.php not called
9 1di Submit Volunteer Information form with a first name that has at least one of each type of valid character and no invalid characters Entered data is accepted and echoed back by demo.php
10 1di Submit Volunteer Information form with a first name that has an invalid character Error is detected and reported with demo.php not called
11 1di Submit Volunteer Information form with first name that is 51 characters long Error is detected and reported with demo.php not called
12 1dii Submit Volunteer Information form with an email address that has at least one of each type of valid character and no invalid characters Entered data is accepted and echoed back by demo.php
13 1dii Submit Volunteer Information form with an email address that has an invalid character Error is detected and reported with demo.php not called
14 1dii Submit Volunteer Information form with an email address that is 51 characters long Error is detected and reported with demo.php not called
15 1dii Submit Volunteer Information form with an email address that does not have an at sign (“@”) Error is detected and reported with demo.php not called
16 1diii Submit Volunteer Information form with a valid age Entered data is accepted and echoed back by demo.php
17 1diii Submit Volunteer Information form with an age that is not numeric Error is detected and reported with demo.php not called
18 1diii Submit Volunteer Information form with an age of 16 Error is detected and reported with demo.php not called
19 1diii Submit Volunteer Information form with an age of 30 Error is detected and reported with demo.php not called
20 1e Submit Volunteer Information form with all valid data Entered data is accepted and echoed back by demo.php
21 2 View each page and check for website title, page title, direct navigation to others pages, same image or background style, same background color, font color, and font style Anticipated elements and consistency is present
22 3 Swap CSS and repeat Test Case #21 Anticipated elements and consistency is present
23 4 Subjective assessment against design guidelines Scored based upon degree of compliance

Submission

Create an archive of your Git repository (you can use GitHub’s “Clone or download” button when viewing your repository for this purpose) and submit that archive to Blackboard. Be sure to include your documentation statement as part of the submission and a brief description of the additional features implemented for the website.

GitHub Classroom also tags the latest commit at the due date for the assignment.

Grading

The following grading rubric will be used for this assignment:

Description Points
XML 10
XML academic schedule 5
Validation of schedule against XSD 5
HTML, CSS, and JavaScript 65
Automated testing (page content and functionality) 50
Consistent layout and navigation 5
Alternative CSS 5
Additional features (graphics, embedded video, interactive JavaScript, etc.) 5

The automated tests, including XML validation, will be executed automatically by Travis CI when you push to your GitHub repository. The remainder of the points, which pertain to visual aesthetics, will be assigned by the instructor by viewing your website. You are strongly encouraged to complete this assignment several days prior to the due date so that you have time to resolve any failures for the automated tests. If you have questions regarding how to interpret their output, do not hesitate to ask the instructor.

Each test case is worth the same amount. No partial credit will be awarded for content and functionality covered by the automated tests (unless you can prove that a test case rejected valid input)!

Automated Tests

Interpreting the output from the automated tests can be non-trivial, and in many cases a single character makes the difference between passing and failing a particular test case. The following examples illustrate how to read the test output.

The following example illustrates a failure where index.html does not contain the required description of the CSL program:

________________ TestIndex.test_contains_description_and_image _________________

self = <web.test_index.TestIndex object at 0x10c1a0d50>
selenium = <selenium.webdriver.chrome.webdriver.WebDriver (session="8631a4f5a3263616288f31eb8f9351b0")>

    def test_contains_description_and_image(self, selenium):
        description = ('The Cadet Service Learning program is designed to '
                       'foster and facilitate service learning activities for '
                       'cadets at the United States Air Force Academy.')

        xpath = ('//body/descendant::*[text()[contains('
                 'normalize-space(.),"{}")]]'.format(description))
        locator = (by.By.XPATH, xpath)
>       assert base.has_element(selenium, *locator), \
            self._create_message('Missing CSL description', locator=locator)
E       AssertionError: Missing CSL description
E             url = http://localhost:8000/index.html
E             locator = xpath://body/descendant::*[text()[contains(normalize-space(.),"The Cadet Service Learning program is designed to foster and facilitate service learning activities for cadets at the United States Air Force Academy.")]]
E       assert False
E        +  where False = <function has_element at 0x10c17cde8>(<selenium.webdriver.chrome.webdriver.WebDriver (session="8631a4f5a3263616288f31eb8f9351b0")>, *('xpath', '//body/descendant::*[text()[contains(normalize-space(.),"The Cadet Service Learning program is designed to foster and facilitate service learning activities for cadets at the United States Air Force Academy.")]]'))
E        +    where <function has_element at 0x10c17cde8> = base.has_element

tests/web/test_index.py:24: AssertionError
------------------------------- pytest-selenium --------------------------------
Driver log: /private/var/folders/g0/365fv8xd31s1vkddd10vnybr0000gn/T/pytest-of-jcoffman/pytest-250/test_contains_description_and_0/driver.log
URL: http://localhost:8000/index.html

The lines of interest are those prefixed by E. The message states, “Missing CSL description” and provides the following information:

url
the location of the page being viewed (i.e., http://localhost:8000/index.html)
locator
the search parameters used to (try to) find the element on the page, which in this case is an XPath expression (i.e., //body/descendant::*[text()[contains(normalize-space(.),"The Cadet Service Learning program is designed to foster and facilitate service learning activities for cadets at the United States Air Force Academy.")]])

In this particular instance, the page being tested contained a typographical mistake: “United Stated Air Force Academy” appeared instead of “United States Air Force Academy.”

Many of the automated tests rely on XPath expressions to interact with elements on the web page. You can enter these expressions into your web browser to see if they identify the intended element to assist with debugging. For example, in Google Chrome, entering $x('xpath-expression') in the JavaScript console returns all elements that match xpath-expression – i.e.,

 > $x('//body/descendant::*[text()[contains(normalize-space(.),"United States Air Force Academy")]]')
<- [p]

where the > indicates the console prompt where an XPath expression in entered and <- indicates the return value, which is a single paragraph element that matched the XPath expression. To debug the prior example, small portions of the search string were validated individually until “United States Air Force Academy” failed to match any elements, at which point the typographical mistake became apparent.

As a second example, consider the following output for testing the volunteer form’s input validation:

________ TestVolunteer.test_form_validation_lastname_invalid_character _________

self = <web.test_volunteer.TestVolunteer object at 0x105d2c210>
selenium = <selenium.webdriver.chrome.webdriver.WebDriver (session="672434e84e3a2aa3ad05a42bcfd23db9")>

    def test_form_validation_lastname_invalid_character(self, selenium):
        for value in ['1', '_', '.', '[', 'invalid 1', 'invalid_']:
>           self._test_form_validation(selenium, 'lastName', value)

tests/web/test_volunteer.py:96:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <web.test_volunteer.TestVolunteer object at 0x105d2c210>
selenium = <selenium.webdriver.chrome.webdriver.WebDriver (session="672434e84e3a2aa3ad05a42bcfd23db9")>
name = 'lastName', value = 'invalid 1', path = '/volunteer.html'

    def _test_form_validation(self, selenium, name, value, path=None):
        if path is None:
            path = self.path

        self._input_form_values(selenium)

        xpath = ('//form[@action="demo.php"]//input[@name="{}"]').format(name)
        inputElement = selenium.find_element(by.By.XPATH, xpath)

        base.set_input_value(selenium, xpath, value)
        inputElement.submit()

>       assert path == urlparse.urlparse(selenium.current_url).path, \
            'Volunteer form submission with {} = "{}"'.format(name, value)
E       AssertionError: Volunteer form submission with lastName = "invalid 1"
E       assert '/volunteer.html' == '/demo.php'
E         - /volunteer.html
E         + /demo.php

tests/web/test_volunteer.py:76: AssertionError
------------------------------- pytest-selenium --------------------------------
Driver log: /private/var/folders/g0/365fv8xd31s1vkddd10vnybr0000gn/T/pytest-of-jcoffman/pytest-256/test_form_validation_lastname_0/driver.log
URL: http://localhost:8000/demo.php

Again, the lines prefixed with E contain the relevant information. The error message, “Volunteer form submission with lastName = ‘invalid 1’,” indicates that an illegal last name was entered (in this case, one that contained digits), but the JavaScript validation did not prevent the submission of the form – i.e., the form was submitted to demo.php.

As a reminder, asking for assistance to interpret the XPath expressions and – more generally – how to replicate a particular test case is explicitly permitted by this assignment’s help policy. (You must, however, document such assistance.)