diff --git a/tests/src/Functional/NavigationalStructureTest.php b/tests/src/Functional/NavigationalStructureTest.php
new file mode 100644
index 0000000..2147a1e
--- /dev/null
+++ b/tests/src/Functional/NavigationalStructureTest.php
@@ -0,0 +1,349 @@
+<?php
+
+namespace Drupal\Tests\eck\Functional;
+
+use Drupal\Core\Url;
+use Drupal\eck\Entity\EckEntityType;
+use Drupal\Tests\BrowserTestBase;
+
+/**
+ * Test ECK's navigational structure. This includes routing, paths, breadcrumbs
+ * and page titles.
+ *
+ * @group ECK
+ */
+class NavigationalStructureTest extends BrowserTestBase {
+
+  public static $modules = ['eck', 'block'];
+  private $baseCrumbs = [
+    'Home',
+    'Administration',
+    'Structure'
+  ];
+  const ECK_ENTITY_TYPE_LIST_TITLE = 'ECK Entity Types';
+
+  /** @var string */
+  private $entityTypeMachineName;
+  /** @var string */
+  private $entityTypeLabel;
+  /** @var string */
+  private $entityBundleMachineName;
+  /** @var string */
+  private $entityBundleLabel;
+
+  public function setUp() {
+    parent::setUp();
+    $user = $this->drupalCreateUser([
+      'administer eck entities',
+      'administer eck entity bundles',
+      'administer eck entity types',
+      'bypass eck entity access',
+      'access administration pages',
+    ]);
+    $this->drupalLogin($user);
+
+    $this->entityTypeMachineName = strtolower($this->randomMachineName());
+    $this->entityTypeLabel = strtolower($this->randomMachineName());
+    $this->createEntityType($this->entityTypeMachineName, $this->entityTypeLabel);
+
+    $this->entityBundleMachineName = strtolower($this->randomMachineName());
+    $this->entityBundleLabel = strtolower($this->entityBundleMachineName);
+    $this->createEntityBundle($this->entityTypeMachineName, $this->entityBundleMachineName, $this->entityBundleLabel);
+
+    $this->placeBlock('system_breadcrumb_block');
+    $this->placeBlock('page_title_block');
+  }
+
+  /**
+   * @param $entityTypeId
+   * @param $entityTypeLabel
+   */
+  protected function createEntityType($entityTypeId, $entityTypeLabel) {
+    $entityType = EckEntityType::create([
+      'id' => $entityTypeId,
+      'label' => $entityTypeLabel
+    ]);
+    $entityType->save();
+  }
+
+  /**
+   * @param $entityTypeId
+   * @param $entityBundleMachineName
+   * @param $entityBundleName
+   */
+  protected function createEntityBundle($entityTypeId, $entityBundleMachineName, $entityBundleName) {
+    $entityBundle = \Drupal::entityTypeManager()
+      ->getStorage($entityTypeId . '_type')
+      ->create([
+        'type' => $entityBundleMachineName,
+        'name' => $entityBundleName
+      ]);
+    $entityBundle->save();
+  }
+
+  /**
+   * @return \Drupal\Core\Entity\EntityInterface
+   */
+  private function createEntity() {
+    $entity = $this->getEntityStorageHandler()
+      ->create(['type' => $this->entityBundleMachineName]);
+    $entity->save();
+    return $entity;
+  }
+
+  /**
+   * @return \Drupal\Core\Entity\EntityStorageInterface
+   */
+  private function getEntityStorageHandler() {
+    return \Drupal::entityTypeManager()
+      ->getStorage($this->entityTypeMachineName);
+  }
+
+  /**
+   * @param $route
+   * @param $routeArguments
+   * @param $expectedUrl
+   * @param $expectedTitle
+   * @param $crumbs
+   */
+  private function assertCorrectPageOnRoute($route, $routeArguments, $expectedUrl, $expectedTitle, $crumbs = []) {
+    $url = Url::fromRoute($route, $routeArguments);
+
+    self::assertEquals($expectedUrl, $url->toString());
+    $this->drupalGet($url);
+    $this->assertTitleEquals($expectedTitle);
+    $this->assertBreadcrumbsVisible(array_merge($this->baseCrumbs, $crumbs));
+  }
+
+  /**
+   * @param string $expectedTitle
+   */
+  private function assertTitleEquals($expectedTitle) {
+    $titleElement = $this->getSession()
+      ->getPage()
+      ->find('css', '.page-title');
+    $this->assertEquals($expectedTitle, $titleElement->getText());
+  }
+
+  /**
+   * @param string[] $expectedBreadcrumbs
+   */
+  private function assertBreadcrumbsVisible(array $expectedBreadcrumbs) {
+    $breadcrumbs = $this->getSession()
+      ->getPage()
+      ->findAll('css', '.breadcrumb a');
+    self::assertEquals(count($expectedBreadcrumbs), count($breadcrumbs));
+    do {
+      $expectedCrumb = array_shift($expectedBreadcrumbs);
+      $actualCrumb = array_shift($breadcrumbs)->getText();
+      self::assertEquals($expectedCrumb, $actualCrumb);
+    } while (!empty($expectedBreadcrumbs));
+  }
+
+  /**
+   * @test
+   */
+  public function entityTypeList() {
+    $route = 'eck.entity_type.list';
+    $routeArguments = [];
+    $expectedUrl = '/admin/structure/eck';
+    $expectedTitle = self::ECK_ENTITY_TYPE_LIST_TITLE;
+
+    $this->assertCorrectPageOnRoute($route, $routeArguments, $expectedUrl, $expectedTitle);
+  }
+
+  /**
+   * @test
+   */
+  public function entityTypeAdd() {
+    $route = 'eck.entity_type.add';
+    $routeArguments = [];
+    $expectedUrl = '/admin/structure/eck/add';
+    $expectedTitle = 'Add entity type';
+    $crumbs = [self::ECK_ENTITY_TYPE_LIST_TITLE];
+
+    $this->assertCorrectPageOnRoute($route, $routeArguments, $expectedUrl, $expectedTitle, $crumbs);
+  }
+
+  /**
+   * @test
+   */
+  public function entityTypeEdit() {
+    $route = 'eck.entity_type.edit';
+    $routeArguments = ['entity_type' => $this->entityTypeMachineName];
+    $expectedUrl = "/admin/structure/eck/edit/{$this->entityTypeMachineName}";
+    $expectedTitle = "Edit {$this->entityTypeLabel}";
+    $crumbs = [self::ECK_ENTITY_TYPE_LIST_TITLE];
+
+    $this->assertCorrectPageOnRoute($route, $routeArguments, $expectedUrl, $expectedTitle, $crumbs);
+  }
+
+  /**
+   * @test
+   */
+  public function entityTypeDelete() {
+    $route = 'eck.entity_type.delete';
+    $routeArguments = ['entity_type' => $this->entityTypeMachineName];
+    $expectedUrl = "/admin/structure/eck/delete/{$this->entityTypeMachineName}";
+    $expectedTitle = "Are you sure you want to delete {$this->entityTypeLabel}?";
+    $crumbs = [
+      self::ECK_ENTITY_TYPE_LIST_TITLE,
+      "Edit {$this->entityTypeLabel}",
+    ];
+
+    $this->assertCorrectPageOnRoute($route, $routeArguments, $expectedUrl, $expectedTitle, $crumbs);
+  }
+
+  /**
+   * @test
+   */
+  public function entityList() {
+    $route = "{$this->entityTypeMachineName}.list";
+    $routeArguments = [];
+    $expectedUrl = "/{$this->entityTypeMachineName}";
+    $expectedTitle = ucfirst("{$this->entityTypeLabel} content");
+
+    $this->assertCorrectPageOnRoute($route, $routeArguments, $expectedUrl, $expectedTitle);
+  }
+
+  /**
+   * @test
+   */
+  public function entityView() {
+    $entity = $this->createEntity();
+
+    $route = "{$this->entityTypeMachineName}.canonical";
+    $routeArguments = [$this->entityTypeMachineName => $entity->id()];
+    $expectedUrl = "{$this->entityTypeMachineName}/{$entity->id()}";
+    $expectedTitle = $this->entityTypeLabel;
+    $this->baseCrumbs = ['Home'];
+
+    $this->assertCorrectPageOnRoute($route, $routeArguments, $expectedUrl, $expectedTitle, []);
+  }
+
+  /**
+   * @test
+   */
+  public function entityAddPage() {
+    $route = "{$this->entityTypeMachineName}.add_page";
+    $expectedUrl = "/{$this->entityTypeMachineName}/add";
+    $expectedTitle = "Create {$this->entityTypeLabel} content";
+
+    $this->assertCorrectPageOnRoute($route, [], $expectedUrl, $expectedTitle);
+  }
+
+  /**
+   * @test
+   */
+  public function entityAdd() {
+    $route = "{$this->entityTypeMachineName}.add";
+    $routeArguments = [
+      'eck_entity_bundle' => $this->entityBundleMachineName
+    ];
+    $expectedUrl = "/{$this->entityTypeMachineName}/content/add/{$this->entityBundleMachineName}";
+    $expectedTitle = "Create {$this->entityBundleMachineName} content";
+
+    $this->assertCorrectPageOnRoute($route, $routeArguments, $expectedUrl, $expectedTitle);
+  }
+
+  /**
+   * @test
+   */
+  public function entityEdit() {
+    $entity = $this->createEntity();
+
+    $route = "{$this->entityTypeMachineName}.edit";
+    $routeArguments = [$this->entityTypeMachineName => $entity->id()];
+    $expectedUrl = "{$this->entityTypeMachineName}/{$entity->id()}/edit";
+    $expectedTitle = "Edit {$this->entityTypeLabel} {$entity->label()}";
+    $crumbs = [
+      $entity->label(),
+    ];
+
+    $this->assertCorrectPageOnRoute($route, $routeArguments, $expectedUrl, $expectedTitle, $crumbs);
+  }
+
+  /**
+   * @test
+   */
+  public function entityDelete() {
+    $entity = $this->createEntity();
+
+    $route = "{$this->entityTypeMachineName}.delete";
+    $routeArguments = [$this->entityTypeMachineName => $entity->id()];
+    $expectedUrl = "{$this->entityTypeMachineName}/{$entity->id()}/delete";
+    $expectedTitle = "Are you sure you wan to delete {$this->entityTypeLabel} {$entity->label()}";
+    $crumbs = [
+      $entity->label(),
+    ];
+
+    $this->assertCorrectPageOnRoute($route, $routeArguments, $expectedUrl, $expectedTitle, $crumbs);
+  }
+
+  /**
+   * @test
+   */
+  public function entityBundleList() {
+    $route = "{$this->entityTypeMachineName}.bundles.list";
+    $routeArguments = [];
+    $expectedUrl = "/admin/structure/eck/{$this->entityTypeMachineName}/bundles";
+    $expectedTitle = ucfirst("{$this->entityTypeLabel} bundles");
+    $crumbs = [
+      self::ECK_ENTITY_TYPE_LIST_TITLE,
+      "Edit {$this->entityTypeLabel}",
+    ];
+
+    $this->assertCorrectPageOnRoute($route, $routeArguments, $expectedUrl, $expectedTitle, $crumbs);
+  }
+
+  /**
+   * @test
+   */
+  public function entityBundleAdd() {
+    $route = "{$this->entityTypeMachineName}.bundles.add";
+    $routeArguments = [];
+    $expectedUrl = "/admin/structure/eck/{$this->entityTypeMachineName}/bundles/add";
+    $expectedTitle = "Add {$this->entityTypeLabel} bundle";
+    $crumbs = [
+      self::ECK_ENTITY_TYPE_LIST_TITLE,
+      "Edit {$this->entityTypeLabel}",
+      ucfirst("{$this->entityTypeLabel} bundles"),
+    ];
+
+    $this->assertCorrectPageOnRoute($route, $routeArguments, $expectedUrl, $expectedTitle, $crumbs);
+  }
+
+  /**
+   * @test
+   */
+  public function entityBundleEdit() {
+    $route = "{$this->entityTypeMachineName}.bundles.edit";
+    $routeArguments = ["eck_entity_bundle" => $this->entityBundleMachineName];
+    $expectedUrl = "/admin/structure/eck/{$this->entityTypeMachineName}/bundles/{$this->entityBundleMachineName}";
+    $expectedTitle = "Edit {$this->entityTypeLabel} bundle {$this->entityBundleLabel}";
+    $crumbs = [
+      self::ECK_ENTITY_TYPE_LIST_TITLE,
+      "Edit {$this->entityTypeLabel}",
+      ucfirst("{$this->entityTypeLabel} bundles"),
+    ];
+
+    $this->assertCorrectPageOnRoute($route, $routeArguments, $expectedUrl, $expectedTitle, $crumbs);
+  }
+
+  /**
+   * @test
+   */
+  public function entityBundleDelete() {
+    $route = "{$this->endsfsdtityTypeMachineName}.bundles.delete";
+    $routeArguments = ["eck_entity_bundle" => $this->entityBundleMachineName];
+    $expectedUrl = "/admin/structure/eck/{$this->entityTypeMachineName}/bundles/{$this->entityBundleMachineName}/delete";
+    $expectedTitle = "Are you sure you want to delete {$this->entityTypeLabel} bundle {$this->entityBundleLabel}?";
+    $crumbs = [
+      self::ECK_ENTITY_TYPE_LIST_TITLE,
+      "Edit {$this->entityTypeLabel}",
+      ucfirst("{$this->entityTypeLabel} bundles"),
+    ];
+
+    $this->assertCorrectPageOnRoute($route, $routeArguments, $expectedUrl, $expectedTitle, $crumbs);
+  }
+}
