[orca] Add support for landmarks and non-landmark forms as spoken context



commit 0c05ad07ca7d5f8ce29cab3561ef72783bc5d8b8
Author: Joanmarie Diggs <jdiggs igalia com>
Date:   Thu Jan 19 17:35:46 2017 -0500

    Add support for landmarks and non-landmark forms as spoken context

 help/C/preferences_general.page                    |    2 +
 help/C/preferences_speech.page                     |   31 +
 src/orca/formatting.py                             |    8 +-
 src/orca/generator.py                              |    2 +
 src/orca/messages.py                               |   46 ++
 src/orca/orca-setup.ui                             |   84 +++-
 src/orca/orca_gui_prefs.py                         |    8 +
 src/orca/script_utilities.py                       |    2 +
 src/orca/scripts/web/script_utilities.py           |    2 +
 src/orca/scripts/web/speech_generator.py           |    2 -
 src/orca/settings.py                               |    8 +
 src/orca/speech_generator.py                       |   45 ++-
 test/html/aria-landmarks2.html                     |   88 +++
 .../firefox/line_nav_aria_landmarks.params         |    1 +
 test/keystrokes/firefox/line_nav_aria_landmarks.py |  573 ++++++++++++++++++++
 .../firefox/line_nav_aria_landmarks.settings       |  171 ++++++
 .../line_nav_aria_landmarks_no_context.params      |    1 +
 .../firefox/line_nav_aria_landmarks_no_context.py  |  536 ++++++++++++++++++
 .../line_nav_aria_landmarks_no_context.settings    |  171 ++++++
 .../firefox/say_all_aria_landmarks.params          |    1 +
 .../firefox/say_all_aria_landmarks.settings        |  171 ++++++
 .../say_all_aria_landmarks_no_context.params       |    1 +
 .../firefox/say_all_aria_landmarks_no_context.py   |   61 ++
 .../say_all_aria_landmarks_no_context.settings     |  171 ++++++
 24 files changed, 2169 insertions(+), 17 deletions(-)
---
diff --git a/help/C/preferences_general.page b/help/C/preferences_general.page
index f6e0e93..411c585 100644
--- a/help/C/preferences_general.page
+++ b/help/C/preferences_general.page
@@ -131,6 +131,8 @@
     </p>
     <list>
       <item><p>Announce blockquotes in Say All</p></item>
+      <item><p>Announce forms in Say All</p></item>
+      <item><p>Announce landmarks in Say All</p></item>
       <item><p>Announce lists in Say All</p></item>
       <item><p>Announce panels in Say All</p></item>
       <item><p>Announce tables in Say All</p></item>
diff --git a/help/C/preferences_speech.page b/help/C/preferences_speech.page
index 0e71c26..dc814f8 100644
--- a/help/C/preferences_speech.page
+++ b/help/C/preferences_speech.page
@@ -223,6 +223,37 @@
         Default value: checked
       </p>
     </section>
+    <section id="announce_forms_during_navigation">
+      <title>Announce forms during navigation</title>
+      <p>
+        If <gui>Announce forms during navigation</gui> is checked,
+        <app>Orca</app> will tell you when you navigate into or out of a
+        form. Note that this setting is specific to forms which are not
+        ARIA landmarks. You can configure the presentation of ARIA landmarks
+        through the <gui>Announce landmarks during navigation</gui> checkbox.
+        In addition, note that this setting is independent of whether or not
+        this announcement is made during Say All. See
+        <link xref="preferences_general#say_all_announce_context">Announce
+        Contextual Information in Say All</link> for more information.
+      </p>
+      <p>
+        Default value: checked
+      </p>
+    </section>
+    <section id="announce_landmarks_during_navigation">
+      <title>Announce landmarks during navigation</title>
+      <p>
+        If <gui>Announce landmarks during navigation</gui> is checked,
+        <app>Orca</app> will tell you when you navigate into or out of an
+        ARIA landmark. Note that this setting is independent of whether or not
+        this announcement is made during Say All. See
+        <link xref="preferences_general#say_all_announce_context">Announce
+        Contextual Information in Say All</link> for more information.
+      </p>
+      <p>
+        Default value: checked
+      </p>
+    </section>
     <section id="announce_lists_during_navigation">
       <title>Announce lists during navigation</title>
       <p>
diff --git a/src/orca/formatting.py b/src/orca/formatting.py
index dc05492..4b4863d 100644
--- a/src/orca/formatting.py
+++ b/src/orca/formatting.py
@@ -193,8 +193,8 @@ formatting = {
             'unfocused': '(displayedText or name) + roleName',
         },
         pyatspi.ROLE_FORM: {
-            'focused': 'labelOrName + readOnly + textRole + currentLineText + allTextSelection',
-            'unfocused': 'labelOrName + readOnly + textRole + currentLineText + allTextSelection + ' + 
MNEMONIC,
+            'focused': 'leaving or (labelAndName + roleName)',
+            'unfocused': '((substring and currentLineText) or labelAndName) + roleName + pause + 
unrelatedLabels'
             },
         pyatspi.ROLE_FRAME: {
             'focused': 'labelOrName + roleName',
@@ -226,6 +226,10 @@ formatting = {
             'unfocused': 'labelAndName + allTextSelection + roleName',
             'basicWhereAmI': 'labelAndName + allTextSelection + roleName'
             },
+        pyatspi.ROLE_LANDMARK: {
+            'focused': 'leaving or (labelAndName + roleName)',
+            'unfocused': '((substring and currentLineText) or labelAndName) + roleName + pause + 
unrelatedLabels'
+            },
         pyatspi.ROLE_LAYERED_PANE: {
             'focused': 'labelAndName + roleName + availability + noShowingChildren',
             'unfocused': 'labelAndName + roleName + availability + noShowingChildren',
diff --git a/src/orca/generator.py b/src/orca/generator.py
index f7f9609..875d099 100644
--- a/src/orca/generator.py
+++ b/src/orca/generator.py
@@ -1172,6 +1172,8 @@ class Generator:
             return 'ROLE_STATIC'
         if self._script.utilities.isBlockquote(obj):
             return pyatspi.ROLE_BLOCK_QUOTE
+        if self._script.utilities.isLandmark(obj):
+            return pyatspi.ROLE_LANDMARK
         if self._script.utilities.isFocusableLabel(obj):
             return pyatspi.ROLE_LIST_ITEM
 
diff --git a/src/orca/messages.py b/src/orca/messages.py
index 321da52..9f9deb2 100644
--- a/src/orca/messages.py
+++ b/src/orca/messages.py
@@ -1039,6 +1039,52 @@ LEARN_MODE_START_SPEECH = \
 LEAVING_BLOCKQUOTE = _("leaving blockquote.")
 
 # Translators: This message is presented when a user is navigating within a
+# form and then navigates out of it.
+LEAVING_FORM = _("leaving form.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_LANDMARK_BANNER = C_("role", "leaving banner.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_LANDMARK_COMPLEMENTARY = C_("role", "leaving complementary content.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_LANDMARK_CONTENTINFO = C_("role", "leaving information.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_LANDMARK_MAIN = C_("role", "leaving main content.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_LANDMARK_NAVIGATION =  C_("role", "leaving navigation.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_LANDMARK_REGION =  C_("role", "leaving region.")
+
+# Translators: This message is presented when a user is navigating within
+# a type of landmark and then navigates out of it. The word or phrase that
+# follows "leaving" should be consistent with the translation provided for
+# the corresponding term with context "role" found in object_properties.py
+LEAVING_LANDMARK_SEARCH = C_("role", "leaving search.")
+
+# Translators: This message is presented when a user is navigating within a
 # list and then navigates out of it.
 LEAVING_LIST = _("leaving list.")
 
diff --git a/src/orca/orca-setup.ui b/src/orca/orca-setup.ui
index 5dfed16..4bc3c67 100644
--- a/src/orca/orca-setup.ui
+++ b/src/orca/orca-setup.ui
@@ -919,7 +919,7 @@
                               </object>
                               <packing>
                                 <property name="left_attach">0</property>
-                                <property name="top_attach">6</property>
+                                <property name="top_attach">8</property>
                               </packing>
                             </child>
                             <child>
@@ -955,7 +955,7 @@
                               </object>
                               <packing>
                                 <property name="left_attach">0</property>
-                                <property name="top_attach">3</property>
+                                <property name="top_attach">5</property>
                               </packing>
                             </child>
                             <child>
@@ -973,7 +973,7 @@
                               </object>
                               <packing>
                                 <property name="left_attach">0</property>
-                                <property name="top_attach">5</property>
+                                <property name="top_attach">7</property>
                               </packing>
                             </child>
                             <child>
@@ -991,6 +991,42 @@
                               </object>
                               <packing>
                                 <property name="left_attach">0</property>
+                                <property name="top_attach">6</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkCheckButton" id="sayAllContextNonLandmarkFormCheckButton">
+                                <property name="label" translatable="yes" comments="Translators: Orca has a 
Say All feature which speaks the entire document. Some users want to hear additional information about what 
is being spoken. If this checkbox is checked, Orca will announce that a form has been entered before speaking 
the contents of that form. At the end of the form, Orca will announce that the form is being 
exited.">Announce _forms in Say All</property>
+                                <property name="use_action_appearance">False</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="use_underline">True</property>
+                                <property name="xalign">0</property>
+                                <property name="active">True</property>
+                                <property name="draw_indicator">True</property>
+                                <signal name="toggled" handler="checkButtonToggled" swapped="no"/>
+                              </object>
+                              <packing>
+                                <property name="left_attach">0</property>
+                                <property name="top_attach">3</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkCheckButton" id="sayAllContextLandmarkCheckButton">
+                                <property name="label" translatable="yes" comments="Translators: Orca has a 
Say All feature which speaks the entire document. Some users want to hear additional information about what 
is being spoken. If this checkbox is checked, Orca will announce when an ARIA landmark has been entered or 
exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of 
webpage like banners, main context, search, etc.">Announce land_marks in Say All</property>
+                                <property name="use_action_appearance">False</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="use_underline">True</property>
+                                <property name="xalign">0</property>
+                                <property name="active">True</property>
+                                <property name="draw_indicator">True</property>
+                                <signal name="toggled" handler="checkButtonToggled" swapped="no"/>
+                              </object>
+                              <packing>
+                                <property name="left_attach">0</property>
                                 <property name="top_attach">4</property>
                               </packing>
                             </child>
@@ -1896,7 +1932,7 @@
                                           </object>
                                           <packing>
                                             <property name="left_attach">0</property>
-                                            <property name="top_attach">9</property>
+                                            <property name="top_attach">11</property>
                                           </packing>
                                         </child>
                                         <child>
@@ -1914,7 +1950,7 @@
                                           </object>
                                           <packing>
                                             <property name="left_attach">0</property>
-                                            <property name="top_attach">11</property>
+                                            <property name="top_attach">13</property>
                                           </packing>
                                         </child>
                                         <child>
@@ -1946,13 +1982,49 @@
                                             <property name="xalign">0</property>
                                             <property name="active">True</property>
                                             <property name="draw_indicator">True</property>
-                                           <signal name="toggled" handler="checkButtonToggled" swapped="no"/>
+                                            <signal name="toggled" handler="checkButtonToggled" 
swapped="no"/>
+                                          </object>
+                                          <packing>
+                                            <property name="left_attach">0</property>
+                                            <property name="top_attach">12</property>
+                                          </packing>
+                                        </child>
+                                        <child>
+                                          <object class="GtkCheckButton" 
id="speakContextLandmarkCheckButton">
+                                            <property name="label" translatable="yes" comments="Translators: 
Orca can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document 
content.  If this checkbox is checked, Orca will announce the ARIA landmark that has been entered as the user 
arrows into it and before speaking the text. Upon navigating out of the landmark, Orca will announce that the 
landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag 
attribute 'role' used to identify important part of webpage like banners, main context, search, 
etc.">Announce land_marks during navigation</property>
+                                            <property name="use_action_appearance">False</property>
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">True</property>
+                                            <property name="receives_default">False</property>
+                                            <property name="use_underline">True</property>
+                                            <property name="xalign">0</property>
+                                            <property name="active">True</property>
+                                            <property name="draw_indicator">True</property>
+                                            <signal name="toggled" handler="checkButtonToggled" 
swapped="no"/>
                                           </object>
                                           <packing>
                                             <property name="left_attach">0</property>
                                             <property name="top_attach">10</property>
                                           </packing>
                                         </child>
+                                        <child>
+                                          <object class="GtkCheckButton" 
id="speakContextNonLandmarkFormCheckButton">
+                                            <property name="label" translatable="yes" comments="Translators: 
Orca can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document 
content. If this checkbox is checked, Orca will announce that a form has been entered as the user arrows into 
it and before speaking the new location. Upon navigating out of the form, Orca will announce that the form 
has been exited prior to speaking the new location.">Announce _forms during navigation</property>
+                                            <property name="use_action_appearance">False</property>
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">True</property>
+                                            <property name="receives_default">False</property>
+                                            <property name="use_underline">True</property>
+                                            <property name="xalign">0</property>
+                                            <property name="active">True</property>
+                                            <property name="draw_indicator">True</property>
+                                            <signal name="toggled" handler="checkButtonToggled" 
swapped="no"/>
+                                          </object>
+                                          <packing>
+                                            <property name="left_attach">0</property>
+                                            <property name="top_attach">9</property>
+                                          </packing>
+                                        </child>
                                       </object>
                                       <packing>
                                         <property name="left_attach">0</property>
diff --git a/src/orca/orca_gui_prefs.py b/src/orca/orca_gui_prefs.py
index eea4d9a..73f5526 100644
--- a/src/orca/orca_gui_prefs.py
+++ b/src/orca/orca_gui_prefs.py
@@ -1326,6 +1326,10 @@ class OrcaSetupGUI(orca_gtkbuilder.GtkBuilderWrapper):
             prefs.get("speakMisspelledIndicator", settings.speakMisspelledIndicator))
         self.get_widget("speakContextBlockquoteCheckButton").set_active(
             prefs.get("speakContextBlockquote", settings.speakContextList))
+        self.get_widget("speakContextLandmarkCheckButton").set_active(
+            prefs.get("speakContextLandmark", settings.speakContextLandmark))
+        self.get_widget("speakContextNonLandmarkFormCheckButton").set_active(
+            prefs.get("speakContextNonLandmarkForm", settings.speakContextNonLandmarkForm))
         self.get_widget("speakContextListCheckButton").set_active(
             prefs.get("speakContextList", settings.speakContextList))
         self.get_widget("speakContextPanelCheckButton").set_active(
@@ -1616,6 +1620,10 @@ class OrcaSetupGUI(orca_gtkbuilder.GtkBuilderWrapper):
             prefs.get("structNavInSayAll", settings.structNavInSayAll))
         self.get_widget("sayAllContextBlockquoteCheckButton").set_active(
             prefs.get("sayAllContextBlockquote", settings.sayAllContextBlockquote))
+        self.get_widget("sayAllContextLandmarkCheckButton").set_active(
+            prefs.get("sayAllContextLandmark", settings.sayAllContextLandmark))
+        self.get_widget("sayAllContextNonLandmarkFormCheckButton").set_active(
+            prefs.get("sayAllContextNonLandmarkForm", settings.sayAllContextNonLandmarkForm))
         self.get_widget("sayAllContextListCheckButton").set_active(
             prefs.get("sayAllContextList", settings.sayAllContextList))
         self.get_widget("sayAllContextPanelCheckButton").set_active(
diff --git a/src/orca/script_utilities.py b/src/orca/script_utilities.py
index b71ac1a..05b7e81 100644
--- a/src/orca/script_utilities.py
+++ b/src/orca/script_utilities.py
@@ -1228,6 +1228,8 @@ class Utilities:
             layoutOnly = True
         elif role == pyatspi.ROLE_LIST:
             layoutOnly = False
+        elif role == pyatspi.ROLE_FORM:
+            layoutOnly = False
         elif self.isTableRow(obj):
             state = obj.getState()
             layoutOnly = not (state.contains(pyatspi.STATE_FOCUSABLE) \
diff --git a/src/orca/scripts/web/script_utilities.py b/src/orca/scripts/web/script_utilities.py
index c839c4f..05aacfb 100644
--- a/src/orca/scripts/web/script_utilities.py
+++ b/src/orca/scripts/web/script_utilities.py
@@ -2075,6 +2075,8 @@ class Utilities(script_utilities.Utilities):
 
         if self.isMath(obj):
             rv = False
+        elif self.isLandmark(obj):
+            rv = False
         else:
             rv = super().isLayoutOnly(obj)
 
diff --git a/src/orca/scripts/web/speech_generator.py b/src/orca/scripts/web/speech_generator.py
index a5d3630..da75fb7 100644
--- a/src/orca/scripts/web/speech_generator.py
+++ b/src/orca/scripts/web/speech_generator.py
@@ -66,7 +66,6 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
                                pyatspi.ROLE_DOCUMENT_WEB,
                                pyatspi.ROLE_EMBEDDED,
                                pyatspi.ROLE_INTERNAL_FRAME,
-                               pyatspi.ROLE_FORM,
                                pyatspi.ROLE_MATH,
                                pyatspi.ROLE_MENU_BAR,
                                pyatspi.ROLE_TOOL_BAR]
@@ -261,7 +260,6 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
 
         if not force:
             doNotSpeak = [pyatspi.ROLE_FOOTER,
-                          pyatspi.ROLE_FORM,
                           pyatspi.ROLE_LABEL,
                           pyatspi.ROLE_MENU_ITEM,
                           pyatspi.ROLE_PARAGRAPH,
diff --git a/src/orca/settings.py b/src/orca/settings.py
index d14ac83..4574201 100644
--- a/src/orca/settings.py
+++ b/src/orca/settings.py
@@ -133,10 +133,14 @@ userCustomizableSettings = [
     "structNavInSayAll",
     "speakContextBlockquote",
     "speakContextPanel",
+    "speakContextLandmark",
+    "speakContextNonLandmarkForm",
     "speakContextList",
     "speakContextTable",
     "sayAllContextBlockquote",
     "sayAllContextPanel",
+    "sayAllContextLandmark",
+    "sayAllContextNonLandmarkForm",
     "sayAllContextList",
     "sayAllContextTable"
 ]
@@ -241,10 +245,14 @@ messagesAreDetailed          = True
 enablePauseBreaks            = True
 speakContextBlockquote       = True
 speakContextPanel            = True
+speakContextNonLandmarkForm  = True
+speakContextLandmark         = True
 speakContextList             = True
 speakContextTable            = True
 sayAllContextBlockquote      = True
 sayAllContextPanel           = True
+sayAllContextNonLandmarkForm = True
+sayAllContextLandmark        = True
 sayAllContextList            = True
 sayAllContextTable           = True
 
diff --git a/src/orca/speech_generator.py b/src/orca/speech_generator.py
index fea7992..3d1e910 100644
--- a/src/orca/speech_generator.py
+++ b/src/orca/speech_generator.py
@@ -1508,6 +1508,8 @@ class SpeechGenerator(generator.Generator):
 
     def _getEnabledAndDisabledContextRoles(self):
         allRoles = [pyatspi.ROLE_BLOCK_QUOTE,
+                    pyatspi.ROLE_FORM,
+                    pyatspi.ROLE_LANDMARK,
                     pyatspi.ROLE_LIST,
                     pyatspi.ROLE_PANEL,
                     pyatspi.ROLE_TABLE]
@@ -1516,19 +1518,27 @@ class SpeechGenerator(generator.Generator):
         if self._script.inSayAll():
             if _settingsManager.getSetting('sayAllContextBlockquote'):
                 enabled.append(pyatspi.ROLE_BLOCK_QUOTE)
+            if _settingsManager.getSetting('sayAllContextLandmark'):
+                enabled.append(pyatspi.ROLE_LANDMARK)
             if _settingsManager.getSetting('sayAllContextList'):
                 enabled.append(pyatspi.ROLE_LIST)
             if _settingsManager.getSetting('sayAllContextPanel'):
                 enabled.append(pyatspi.ROLE_PANEL)
+            if _settingsManager.getSetting('sayAllContextNonLandmarkForm'):
+                enabled.append(pyatspi.ROLE_FORM)
             if _settingsManager.getSetting('sayAllContextTable'):
                 enabled.append(pyatspi.ROLE_TABLE)
         else:
             if _settingsManager.getSetting('speakContextBlockquote'):
                 enabled.append(pyatspi.ROLE_BLOCK_QUOTE)
+            if _settingsManager.getSetting('speakContextLandmark'):
+                enabled.append(pyatspi.ROLE_LANDMARK)
             if _settingsManager.getSetting('speakContextList'):
                 enabled.append(pyatspi.ROLE_LIST)
             if _settingsManager.getSetting('speakContextPanel'):
                 enabled.append(pyatspi.ROLE_PANEL)
+            if _settingsManager.getSetting('speakContextNonLandmarkForm'):
+                enabled.append(pyatspi.ROLE_FORM)
             if _settingsManager.getSetting('speakContextTable'):
                 enabled.append(pyatspi.ROLE_TABLE)
 
@@ -1539,7 +1549,7 @@ class SpeechGenerator(generator.Generator):
         if not args.get('leaving'):
             return []
 
-        role = args.get('role', obj.getRole)
+        role = args.get('role', obj.getRole())
         enabled, disabled = self._getEnabledAndDisabledContextRoles()
         if not role in enabled:
             return []
@@ -1549,13 +1559,31 @@ class SpeechGenerator(generator.Generator):
             result.append(messages.LEAVING_BLOCKQUOTE)
         elif role == pyatspi.ROLE_LIST and self._script.utilities.isDocumentList(obj):
             result.append(messages.LEAVING_LIST)
-        elif role == pyatspi.ROLE_PANEL:
-            if self._script.utilities.isDocumentPanel(obj):
-                result.append(messages.LEAVING_PANEL)
-            else:
-                result = ['']
+        elif role == pyatspi.ROLE_PANEL and self._script.utilities.isDocumentPanel(obj):
+            result.append(messages.LEAVING_PANEL)
         elif role == pyatspi.ROLE_TABLE and self._script.utilities.isTextDocumentTable(obj):
             result.append(messages.LEAVING_TABLE)
+        elif self._script.utilities.isLandmark(obj):
+            if self._script.utilities.isLandmarkBanner(obj):
+                result.append(messages.LEAVING_LANDMARK_BANNER)
+            if self._script.utilities.isLandmarkComplementary(obj):
+                result.append(messages.LEAVING_LANDMARK_COMPLEMENTARY)
+            if self._script.utilities.isLandmarkContentInfo(obj):
+                result.append(messages.LEAVING_LANDMARK_CONTENTINFO)
+            if self._script.utilities.isLandmarkMain(obj):
+                result.append(messages.LEAVING_LANDMARK_MAIN)
+            if self._script.utilities.isLandmarkNavigation(obj):
+                result.append(messages.LEAVING_LANDMARK_NAVIGATION)
+            if self._script.utilities.isLandmarkRegion(obj):
+                result.append(messages.LEAVING_LANDMARK_REGION)
+            if self._script.utilities.isLandmarkSearch(obj):
+                result.append(messages.LEAVING_LANDMARK_SEARCH)
+            if self._script.utilities.isLandmarkForm(obj):
+                result.append(messages.LEAVING_FORM)
+        elif role == pyatspi.ROLE_FORM:
+            result.append(messages.LEAVING_FORM)
+        else:
+            result = ['']
         if result:
             result.extend(self.voice(SYSTEM))
 
@@ -1634,7 +1662,8 @@ class SpeechGenerator(generator.Generator):
                     self._restoreRole(oldRole, args)
                 parent = parent.parent
 
-        result.reverse()
+        if not leaving:
+            result.reverse()
         return result
 
     def _generateOldAncestors(self, obj, **args):
@@ -1658,6 +1687,8 @@ class SpeechGenerator(generator.Generator):
 
         args['leaving'] = True
         args['includeOnly'] = [pyatspi.ROLE_BLOCK_QUOTE,
+                               pyatspi.ROLE_FORM,
+                               pyatspi.ROLE_LANDMARK,
                                pyatspi.ROLE_LIST,
                                pyatspi.ROLE_PANEL,
                                pyatspi.ROLE_SECTION,
diff --git a/test/html/aria-landmarks2.html b/test/html/aria-landmarks2.html
new file mode 100644
index 0000000..5a63232
--- /dev/null
+++ b/test/html/aria-landmarks2.html
@@ -0,0 +1,88 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<style type="text/css">
+       div {
+               padding: 2%;
+               border: solid 2px #000000;
+               margin: 10px;
+               white-space: inherit;
+       }
+       form {
+               padding: 2%;
+               border: dashed 2px #000000;
+               margin: 10px;
+               white-space: inherit;
+       }
+       #banner {height:100px;background:#ff8c00 }
+       #navigation {float:left;
+               width:15%;
+               height:600px;
+               background:#7fff00}
+       #main {float:left;
+               width:50%;
+               height:600px;
+               background:#f0e68c}
+       #complementary {float:left;width:15%;height:600px;background:#4682b4}
+       #contentinfo {clear:both;height:100px;background:#ffb6c1}
+       #search {background:#ffff00;}
+       #form {background:#fafad2;}
+       #region {background: #cccccc;}
+</style>
+
+</head>
+
+<body>
+<p>Start of test</p>
+<div id="banner" role="banner">
+  <p>Line one</p>
+  <p>Line two</p>
+  <button>Click me</button>
+</div>
+<div id="navigation" role="navigation">
+  <p>Line one</p>
+  <p>Line two</p>
+  <button>Click me</button>
+</div>
+<div id="main" role="main">
+  <p>Line one</p>
+  <p>Line two</p>
+  <button>Click me</button>
+  <div id="region" role="region" aria-label="My nifty foo">
+    <p>Line one</p>
+    <p>Line two</p>
+    <button>Click me</button>
+   </div>
+    <p>Line four</p>
+    <p>Line five</p>
+</div>
+<div id="complementary" role="complementary">
+  <p>Line one</p>
+  <p>Line two</p>
+  <button>Click me</button>
+  <div role="form" id="form">
+    <p>Line one</p>
+    <p>Line two</p>
+    <button>Click me</button>
+  </div>
+  <p>Line four</p>
+  <form>
+    <p>Line one</p>
+    <p>Line two</p>
+    <button>Click me</button>
+  </form>
+  <p>Line five</p>
+  <div id="search" role="search">
+    <p>Line one</p>
+    <p>Line two</p>
+    <button>Click me</button>
+  </div>
+</div>
+<div id="contentinfo" role="contentinfo">
+  <p>Line one</p>
+  <p>Line two</p>
+  <button>Click me</button>
+</div>
+<p>End of test</p>
+</body>
+</html>
diff --git a/test/keystrokes/firefox/line_nav_aria_landmarks.params 
b/test/keystrokes/firefox/line_nav_aria_landmarks.params
new file mode 100644
index 0000000..b44dd8f
--- /dev/null
+++ b/test/keystrokes/firefox/line_nav_aria_landmarks.params
@@ -0,0 +1 @@
+PARAMS=$TEST_DIR/../../html/aria-landmarks2.html
diff --git a/test/keystrokes/firefox/line_nav_aria_landmarks.py 
b/test/keystrokes/firefox/line_nav_aria_landmarks.py
new file mode 100644
index 0000000..fc39302
--- /dev/null
+++ b/test/keystrokes/firefox/line_nav_aria_landmarks.py
@@ -0,0 +1,573 @@
+#!/usr/bin/python
+
+"""Test of line navigation output of Firefox."""
+
+from macaroon.playback import *
+import utils
+
+sequence = MacroSequence()
+
+#sequence.append(WaitForDocLoad())
+sequence.append(PauseAction(5000))
+sequence.append(KeyComboAction("Tab"))
+sequence.append(PauseAction(2000))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("<Control>Home"))
+sequence.append(utils.AssertPresentationAction(
+    "1. Top of file",
+    ["BRAILLE LINE:  'Start of test'",
+     "     VISIBLE:  'Start of test', cursor=1",
+     "SPEECH OUTPUT: 'leaving banner.'",
+     "SPEECH OUTPUT: 'Start of test'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "2. Line Down",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'banner'",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "3. Line Down",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "4. Line Down",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "5. Line Down",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'leaving banner.'",
+     "SPEECH OUTPUT: 'navigation'",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "6. Line Down",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "7. Line Down",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "8. Line Down",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'leaving navigation.'",
+     "SPEECH OUTPUT: 'main content'",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "9. Line Down",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "10. Line Down",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "11. Line Down",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'My nifty foo region'",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "12. Line Down",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "13. Line Down",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "14. Line Down",
+    ["BRAILLE LINE:  'Line four'",
+     "     VISIBLE:  'Line four', cursor=1",
+     "SPEECH OUTPUT: 'leaving region.'",
+     "SPEECH OUTPUT: 'Line four'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "15. Line Down",
+    ["BRAILLE LINE:  'Line five'",
+     "     VISIBLE:  'Line five', cursor=1",
+     "SPEECH OUTPUT: 'Line five'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "16. Line Down",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'leaving main content.'",
+     "SPEECH OUTPUT: 'complementary content'",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "17. Line Down",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "18. Line Down",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "19. Line Down",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'form'",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "20. Line Down",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "21. Line Down",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "22. Line Down",
+    ["BRAILLE LINE:  'Line four'",
+     "     VISIBLE:  'Line four', cursor=1",
+     "SPEECH OUTPUT: 'leaving form.'",
+     "SPEECH OUTPUT: 'Line four'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "23. Line Down",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'form'",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "24. Line Down",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "25. Line Down",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "26. Line Down",
+    ["BRAILLE LINE:  'Line five'",
+     "     VISIBLE:  'Line five', cursor=1",
+     "SPEECH OUTPUT: 'leaving form.'",
+     "SPEECH OUTPUT: 'Line five'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "27. Line Down",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'search'",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "28. Line Down",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "29. Line Down",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "30. Line Down",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'leaving search.'",
+     "SPEECH OUTPUT: 'leaving complementary content.'",
+     "SPEECH OUTPUT: 'information'",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "31. Line Down",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "32. Line Down",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "33. Line Down",
+    ["BRAILLE LINE:  'End of test'",
+     "     VISIBLE:  'End of test', cursor=1",
+     "SPEECH OUTPUT: 'leaving information.'",
+     "SPEECH OUTPUT: 'End of test'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "34. Line Up",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'information'",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "35. Line Up",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "36. Line Up",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "37. Line Up",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'leaving information.'",
+     "SPEECH OUTPUT: 'complementary content'",
+     "SPEECH OUTPUT: 'search'",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "38. Line Up",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "39. Line Up",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "40. Line Up",
+    ["BRAILLE LINE:  'Line five'",
+     "     VISIBLE:  'Line five', cursor=1",
+     "SPEECH OUTPUT: 'leaving search.'",
+     "SPEECH OUTPUT: 'Line five'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "41. Line Up",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'form'",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "42. Line Up",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "43. Line Up",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "44. Line Up",
+    ["BRAILLE LINE:  'Line four'",
+     "     VISIBLE:  'Line four', cursor=1",
+     "SPEECH OUTPUT: 'leaving form.'",
+     "SPEECH OUTPUT: 'Line four'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "45. Line Up",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'form'",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "46. Line Up",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "47. Line Up",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "48. Line Up",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'leaving form.'",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "49. Line Up",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "50. Line Up",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "51. Line Up",
+    ["BRAILLE LINE:  'Line five'",
+     "     VISIBLE:  'Line five', cursor=1",
+     "SPEECH OUTPUT: 'leaving complementary content.'",
+     "SPEECH OUTPUT: 'main content'",
+     "SPEECH OUTPUT: 'Line five'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "52. Line Up",
+    ["BRAILLE LINE:  'Line four'",
+     "     VISIBLE:  'Line four', cursor=1",
+     "SPEECH OUTPUT: 'Line four'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "53. Line Up",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'My nifty foo region'",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "54. Line Up",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "55. Line Up",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "56. Line Up",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'leaving region.'",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "57. Line Up",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "58. Line Up",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "59. Line Up",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'leaving main content.'",
+     "SPEECH OUTPUT: 'navigation'",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "60. Line Up",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "61. Line Up",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "62. Line Up",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'leaving navigation.'",
+     "SPEECH OUTPUT: 'banner'",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "63. Line Up",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "64. Line Up",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "65. Line Up",
+    ["BRAILLE LINE:  'Start of test'",
+     "     VISIBLE:  'Start of test', cursor=1",
+     "SPEECH OUTPUT: 'leaving banner.'",
+     "SPEECH OUTPUT: 'Start of test'"]))
+
+sequence.append(utils.AssertionSummaryAction())
+sequence.start()
diff --git a/test/keystrokes/firefox/line_nav_aria_landmarks.settings 
b/test/keystrokes/firefox/line_nav_aria_landmarks.settings
new file mode 100644
index 0000000..1a09f14
--- /dev/null
+++ b/test/keystrokes/firefox/line_nav_aria_landmarks.settings
@@ -0,0 +1,171 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": true,
+        "sayAllContextLandmark": true,
+        "sayAllContextPanel": true,
+        "sayAllContextNonLandmarkForm": true,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": true,
+        "speakContextLandmark": true,
+        "speakContextPanel": true,
+        "speakContextNonLandmarkForm": true,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": true,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "established": false
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": true,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": true,
+        "speakContextBlockquote": true,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "established": false
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/firefox/line_nav_aria_landmarks_no_context.params 
b/test/keystrokes/firefox/line_nav_aria_landmarks_no_context.params
new file mode 100644
index 0000000..b44dd8f
--- /dev/null
+++ b/test/keystrokes/firefox/line_nav_aria_landmarks_no_context.params
@@ -0,0 +1 @@
+PARAMS=$TEST_DIR/../../html/aria-landmarks2.html
diff --git a/test/keystrokes/firefox/line_nav_aria_landmarks_no_context.py 
b/test/keystrokes/firefox/line_nav_aria_landmarks_no_context.py
new file mode 100644
index 0000000..540f55e
--- /dev/null
+++ b/test/keystrokes/firefox/line_nav_aria_landmarks_no_context.py
@@ -0,0 +1,536 @@
+#!/usr/bin/python
+
+"""Test of line navigation output of Firefox."""
+
+from macaroon.playback import *
+import utils
+
+sequence = MacroSequence()
+
+#sequence.append(WaitForDocLoad())
+sequence.append(PauseAction(5000))
+sequence.append(KeyComboAction("Tab"))
+sequence.append(PauseAction(2000))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("<Control>Home"))
+sequence.append(utils.AssertPresentationAction(
+    "1. Top of file",
+    ["BRAILLE LINE:  'Start of test'",
+     "     VISIBLE:  'Start of test', cursor=1",
+     "SPEECH OUTPUT: 'Start of test'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "2. Line Down",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "3. Line Down",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "4. Line Down",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "5. Line Down",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "6. Line Down",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "7. Line Down",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "8. Line Down",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "9. Line Down",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "10. Line Down",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "11. Line Down",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "12. Line Down",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "13. Line Down",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "14. Line Down",
+    ["BRAILLE LINE:  'Line four'",
+     "     VISIBLE:  'Line four', cursor=1",
+     "SPEECH OUTPUT: 'Line four'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "15. Line Down",
+    ["BRAILLE LINE:  'Line five'",
+     "     VISIBLE:  'Line five', cursor=1",
+     "SPEECH OUTPUT: 'Line five'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "16. Line Down",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "17. Line Down",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "18. Line Down",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "19. Line Down",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "20. Line Down",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "21. Line Down",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "22. Line Down",
+    ["BRAILLE LINE:  'Line four'",
+     "     VISIBLE:  'Line four', cursor=1",
+     "SPEECH OUTPUT: 'Line four'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "23. Line Down",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "24. Line Down",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "25. Line Down",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "26. Line Down",
+    ["BRAILLE LINE:  'Line five'",
+     "     VISIBLE:  'Line five', cursor=1",
+     "SPEECH OUTPUT: 'Line five'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "27. Line Down",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "28. Line Down",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "29. Line Down",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "30. Line Down",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "31. Line Down",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "32. Line Down",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+    "33. Line Down",
+    ["BRAILLE LINE:  'End of test'",
+     "     VISIBLE:  'End of test', cursor=1",
+     "SPEECH OUTPUT: 'End of test'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "34. Line Up",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "35. Line Up",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "36. Line Up",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "37. Line Up",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "38. Line Up",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "39. Line Up",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "40. Line Up",
+    ["BRAILLE LINE:  'Line five'",
+     "     VISIBLE:  'Line five', cursor=1",
+     "SPEECH OUTPUT: 'Line five'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "41. Line Up",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "42. Line Up",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "43. Line Up",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "44. Line Up",
+    ["BRAILLE LINE:  'Line four'",
+     "     VISIBLE:  'Line four', cursor=1",
+     "SPEECH OUTPUT: 'Line four'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "45. Line Up",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "46. Line Up",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "47. Line Up",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "48. Line Up",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "49. Line Up",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "50. Line Up",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "51. Line Up",
+    ["BRAILLE LINE:  'Line five'",
+     "     VISIBLE:  'Line five', cursor=1",
+     "SPEECH OUTPUT: 'Line five'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "52. Line Up",
+    ["BRAILLE LINE:  'Line four'",
+     "     VISIBLE:  'Line four', cursor=1",
+     "SPEECH OUTPUT: 'Line four'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "53. Line Up",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "54. Line Up",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "55. Line Up",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "56. Line Up",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "57. Line Up",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "58. Line Up",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "59. Line Up",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "60. Line Up",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "61. Line Up",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "62. Line Up",
+    ["BRAILLE LINE:  'Click me push button'",
+     "     VISIBLE:  'Click me push button', cursor=1",
+     "SPEECH OUTPUT: 'Click me push button'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "63. Line Up",
+    ["BRAILLE LINE:  'Line two'",
+     "     VISIBLE:  'Line two', cursor=1",
+     "SPEECH OUTPUT: 'Line two'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "64. Line Up",
+    ["BRAILLE LINE:  'Line one'",
+     "     VISIBLE:  'Line one', cursor=1",
+     "SPEECH OUTPUT: 'Line one'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+    "65. Line Up",
+    ["BRAILLE LINE:  'Start of test'",
+     "     VISIBLE:  'Start of test', cursor=1",
+     "SPEECH OUTPUT: 'Start of test'"]))
+
+sequence.append(utils.AssertionSummaryAction())
+sequence.start()
diff --git a/test/keystrokes/firefox/line_nav_aria_landmarks_no_context.settings 
b/test/keystrokes/firefox/line_nav_aria_landmarks_no_context.settings
new file mode 100644
index 0000000..a41f4cf
--- /dev/null
+++ b/test/keystrokes/firefox/line_nav_aria_landmarks_no_context.settings
@@ -0,0 +1,171 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": false,
+        "sayAllContextLandmark": false,
+        "sayAllContextPanel": false,
+        "sayAllContextNonLandmarkForm": false,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": false,
+        "speakContextLandmark": false,
+        "speakContextPanel": false,
+        "speakContextNonLandmarkForm": false,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": false,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "established": false
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": false,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": false,
+        "speakContextBlockquote": false,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "established": false
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/firefox/say_all_aria_landmarks.params 
b/test/keystrokes/firefox/say_all_aria_landmarks.params
new file mode 100644
index 0000000..b44dd8f
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_aria_landmarks.params
@@ -0,0 +1 @@
+PARAMS=$TEST_DIR/../../html/aria-landmarks2.html
diff --git a/test/keystrokes/firefox/say_all_aria_landmarks.settings 
b/test/keystrokes/firefox/say_all_aria_landmarks.settings
new file mode 100644
index 0000000..1a09f14
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_aria_landmarks.settings
@@ -0,0 +1,171 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": true,
+        "sayAllContextLandmark": true,
+        "sayAllContextPanel": true,
+        "sayAllContextNonLandmarkForm": true,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": true,
+        "speakContextLandmark": true,
+        "speakContextPanel": true,
+        "speakContextNonLandmarkForm": true,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": true,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "established": false
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": true,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": true,
+        "speakContextBlockquote": true,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "established": false
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file
diff --git a/test/keystrokes/firefox/say_all_aria_landmarks_no_context.params 
b/test/keystrokes/firefox/say_all_aria_landmarks_no_context.params
new file mode 100644
index 0000000..b44dd8f
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_aria_landmarks_no_context.params
@@ -0,0 +1 @@
+PARAMS=$TEST_DIR/../../html/aria-landmarks2.html
diff --git a/test/keystrokes/firefox/say_all_aria_landmarks_no_context.py 
b/test/keystrokes/firefox/say_all_aria_landmarks_no_context.py
new file mode 100644
index 0000000..f859b46
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_aria_landmarks_no_context.py
@@ -0,0 +1,61 @@
+#!/usr/bin/python
+
+"""Test of sayAll."""
+
+from macaroon.playback import *
+import utils
+
+sequence = MacroSequence()
+
+#sequence.append(WaitForDocLoad())
+sequence.append(PauseAction(5000))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("KP_Add"))
+sequence.append(utils.AssertPresentationAction(
+    "1. KP_Add to do a SayAll",
+    ["SPEECH OUTPUT: 'Start of test'",
+     "SPEECH OUTPUT: 'Line one'",
+     "SPEECH OUTPUT: 'Line two'",
+     "SPEECH OUTPUT: 'Click me'",
+     "SPEECH OUTPUT: 'push button'",
+     "SPEECH OUTPUT: 'Line one'",
+     "SPEECH OUTPUT: 'Line two'",
+     "SPEECH OUTPUT: 'Click me'",
+     "SPEECH OUTPUT: 'push button'",
+     "SPEECH OUTPUT: 'Line one'",
+     "SPEECH OUTPUT: 'Line two'",
+     "SPEECH OUTPUT: 'Click me'",
+     "SPEECH OUTPUT: 'push button'",
+     "SPEECH OUTPUT: 'Line one'",
+     "SPEECH OUTPUT: 'Line two'",
+     "SPEECH OUTPUT: 'Click me'",
+     "SPEECH OUTPUT: 'push button'",
+     "SPEECH OUTPUT: 'Line four'",
+     "SPEECH OUTPUT: 'Line five'",
+     "SPEECH OUTPUT: 'Line one'",
+     "SPEECH OUTPUT: 'Line two'",
+     "SPEECH OUTPUT: 'Click me'",
+     "SPEECH OUTPUT: 'push button'",
+     "SPEECH OUTPUT: 'Line one'",
+     "SPEECH OUTPUT: 'Line two'",
+     "SPEECH OUTPUT: 'Click me'",
+     "SPEECH OUTPUT: 'push button'",
+     "SPEECH OUTPUT: 'Line four'",
+     "SPEECH OUTPUT: 'Line one'",
+     "SPEECH OUTPUT: 'Line two'",
+     "SPEECH OUTPUT: 'Click me'",
+     "SPEECH OUTPUT: 'push button'",
+     "SPEECH OUTPUT: 'Line five'",
+     "SPEECH OUTPUT: 'Line one'",
+     "SPEECH OUTPUT: 'Line two'",
+     "SPEECH OUTPUT: 'Click me'",
+     "SPEECH OUTPUT: 'push button'",
+     "SPEECH OUTPUT: 'Line one'",
+     "SPEECH OUTPUT: 'Line two'",
+     "SPEECH OUTPUT: 'Click me'",
+     "SPEECH OUTPUT: 'push button'",
+     "SPEECH OUTPUT: 'End of test'"]))
+
+sequence.append(utils.AssertionSummaryAction())
+sequence.start()
diff --git a/test/keystrokes/firefox/say_all_aria_landmarks_no_context.settings 
b/test/keystrokes/firefox/say_all_aria_landmarks_no_context.settings
new file mode 100644
index 0000000..a41f4cf
--- /dev/null
+++ b/test/keystrokes/firefox/say_all_aria_landmarks_no_context.settings
@@ -0,0 +1,171 @@
+{
+    "general": {
+        "enabledSpokenTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; paragraph-style:; text-spelling:none; fg-color:; 
bg-color:;",
+        "orcaModifierKeys": [
+            "Insert",
+            "KP_Insert"
+        ],
+        "skipBlankCells": false,
+        "onlySpeakDisplayedText": false,
+        "enableMnemonicSpeaking": false,
+        "chatAnnounceBuddyTyping": false,
+        "messagesAreDetailed": true,
+        "speakProgressBarUpdates": true,
+        "speakCellCoordinates": true,
+        "enableAlphabeticKeys": true,
+        "enableBraille": false,
+        "brailleAlignmentStyle": 0,
+        "playSoundForPositionInSet": false,
+        "sayAllStyle": 1,
+        "enableEchoBySentence": false,
+        "chatSpeakRoomName": false,
+        "soundVolume": 0.5,
+        "activeProfile": [
+            "Default",
+            "default"
+        ],
+        "brailleVerbosityLevel": 1,
+        "sayAllContextTable": false,
+        "sayAllContextLandmark": false,
+        "sayAllContextPanel": false,
+        "sayAllContextNonLandmarkForm": false,
+        "enableTutorialMessages": false,
+        "wrappedStructuralNavigation": true,
+        "capitalizationStyle": "none",
+        "findResultsMinimumLength": 4,
+        "enableContractedBraille": false,
+        "presentDateFormat": "%x",
+        "enableSpeechIndentation": false,
+        "brailleContractionTable": "",
+        "structNavTriggersFocusMode": false,
+        "enablePauseBreaks": true,
+        "speakNumbersAsDigits": false,
+        "spellcheckSpellError": true,
+        "useColorNames": true,
+        "speakContextTable": false,
+        "speakContextLandmark": false,
+        "speakContextPanel": false,
+        "speakContextNonLandmarkForm": false,
+        "readFullRowInGUITable": true,
+        "enabledBrailledTextAttributes": "size:; family-name:; weight:400; indent:0; underline:none; 
strikethrough:false; justification:left; style:normal; text-spelling:none;",
+        "enableSpace": true,
+        "brailleSelectorIndicator": 192,
+        "profile": [
+            "Default",
+            "default"
+        ],
+        "verbalizePunctuationStyle": 1,
+        "enableBrailleContext": true,
+        "enableNavigationKeys": false,
+        "structNavInSayAll": false,
+        "enableSound": true,
+        "speakCellSpan": true,
+        "speechVerbosityLevel": 1,
+        "brailleRolenameStyle": 1,
+        "mouseDwellDelay": null,
+        "enableSpeech": true,
+        "caretNavTriggersFocusMode": false,
+        "enableDiacriticalKeys": false,
+        "findResultsVerbosity": 2,
+        "sayAllContextBlockquote": false,
+        "speakBlankLines": true,
+        "speakSpreadsheetCoordinates": true,
+        "flashIsPersistent": false,
+        "enableNumericKeys": true,
+        "enableFlashMessages": true,
+        "progressBarVerbosity": 1,
+        "brailleLinkIndicator": 192,
+        "presentTimeFormat": "%X",
+        "enablePunctuationKeys": true,
+        "enableKeyEcho": false,
+        "playSoundForState": false,
+        "beepProgressBarUpdates": false,
+        "enableFunctionKeys": true,
+        "speakMisspelledIndicator": true,
+        "textAttributesBrailleIndicator": 0,
+        "voices": {
+            "default": {
+                "established": false
+            },
+            "system": {
+                "established": false
+            },
+            "uppercase": {
+                "average-pitch": 7.0
+            },
+            "hyperlink": {
+                "established": false
+            }
+        },
+        "enableBrailleMonitor": true,
+        "layoutMode": true,
+        "brailleFlashTime": 5000,
+        "largeObjectTextLength": 75,
+        "speakContextList": false,
+        "ignoreStatusBarProgressBars": true,
+        "keyboardLayout": 1,
+        "brailleProgressBarUpdates": false,
+        "readFullRowInSpreadSheet": false,
+        "enableActionKeys": true,
+        "enablePositionSpeaking": false,
+        "structuralNavigationEnabled": true,
+        "playSoundForRole": false,
+        "disableBrailleEOL": false,
+        "presentToolTips": false,
+        "enableMouseReview": false,
+        "speechServerFactory": "speechdispatcherfactory",
+        "chatMessageVerbosity": 0,
+        "enableEchoByWord": false,
+        "spellcheckSpellSuggestion": true,
+        "enableModifierKeys": true,
+        "speakMultiCaseStringsAsWords": false,
+        "flashIsDetailed": true,
+        "speakCellHeaders": true,
+        "rewindAndFastForwardInSayAll": false,
+        "sayAllContextList": false,
+        "speakContextBlockquote": false,
+        "enableEchoByCharacter": false,
+        "playSoundForValue": false,
+        "progressBarUpdateInterval": 10,
+        "spellcheckPresentContext": true,
+        "speechServerInfo": null,
+        "chatRoomHistories": false,
+        "readFullRowInDocumentTable": true,
+        "startingProfile": [
+            "Default",
+            "default"
+        ]
+    },
+    "keybindings": {},
+    "profiles": {
+        "default": {
+            "profile": [
+                "Default",
+                "default"
+            ],
+            "brailleContractionTable": "/usr/share/liblouis/tables/en-us-compbrl.ctb",
+            "voices": {
+                "default": {
+                    "established": false
+                },
+                "system": {
+                    "established": false
+                },
+                "uppercase": {
+                    "average-pitch": 7.0
+                },
+                "hyperlink": {
+                    "established": false
+                }
+            },
+            "pronunciations": {},
+            "speechServerInfo": [
+                "Default Synthesizer",
+                "default"
+            ],
+            "keybindings": {},
+            "speechServerFactory": "orca.speechdispatcherfactory"
+        }
+    },
+    "pronunciations": {}
+}
\ No newline at end of file


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]