diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml
new file mode 100644
index 0000000..e9c4015
--- /dev/null
+++ b/.github/workflows/run-tests.yml
@@ -0,0 +1,43 @@
+name: Unit Tests
+
+on:
+  push:
+    branches:
+    - master
+  pull_request:
+    branches:
+    - "*"
+  schedule:
+  - cron: '0 0 * * *'
+
+jobs:
+  php-tests:
+    runs-on: ubuntu-latest
+    timeout-minutes: 15
+    env:
+      COMPOSER_NO_INTERACTION: 1
+
+    strategy:
+      fail-fast: false
+      matrix:
+        php: [8.3, 8.2]
+
+    name: P${{ matrix.php }}
+
+    steps:
+    - name: Checkout code
+      uses: actions/checkout@v4
+
+    - name: Setup PHP
+      uses: shivammathur/setup-php@v2
+      with:
+        php-version: ${{ matrix.php }}
+        coverage: none
+        tools: composer:v2
+
+    - name: Install dependencies
+      run: |
+        composer install -o --quiet
+
+    - name: Execute Unit Tests
+      run: composer test
diff --git a/.gitignore b/.gitignore
index 8879189..6bef520 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@
 composer.phar
 composer.lock
 .DS_Store
+.phpunit.result.cache
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index d7e4828..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-language: php
-
-php:
-  - 5.5
-  - 5.6
-  - 7.0
-
-before_script:
-  - curl -s http://getcomposer.org/installer | php
-  - php composer.phar install --dev
-
-script: phpunit
\ No newline at end of file
diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
index e1d837b..dcb7bb0 100644
--- a/CHANGELOG.markdown
+++ b/CHANGELOG.markdown
@@ -1,4 +1,14 @@
-### 4.2.8
+### 4.3.4
+*   Support Laravel 5.8
+
+### 4.3.3
+*   Support Laravel 5.7
+
+### 4.3.2
+*   Support Laravel 5.6
+*   Added `nestedSet` and `dropNestedSet` blueprint macros
+
+### 4.3.0
 *   Support Laravel 5.5
 *   Added `fixSubtree` and `rebuildSubtree` methods
 *   Increased performance of tree rebuilding
@@ -104,4 +114,4 @@
 ### 1.1.0
 
 *   `Collection::toDictionary` is now obsolete. Use `Collection::groupBy`.
-*   Laravel 4.2 is required
\ No newline at end of file
+*   Laravel 4.2 is required
diff --git a/README.markdown b/README.markdown
index 06ba4d7..f4d2d51 100644
--- a/README.markdown
+++ b/README.markdown
@@ -4,17 +4,18 @@
 [![Latest Unstable Version](https://poser.pugx.org/kalnoy/nestedset/v/unstable.svg)](https://packagist.org/packages/kalnoy/nestedset)
 [![License](https://poser.pugx.org/kalnoy/nestedset/license.svg)](https://packagist.org/packages/kalnoy/nestedset)
 
-This is a Laravel 4-5 package for working with trees in relational databases.
-
-*   **Laravel 5.2, 5.3, 5.4, 5.5** is supported since v4
+This is a Laravel 4-11 package for working with trees in relational databases.
+
+*   **Laravel 11.0** is supported since v7
+*   **Laravel 10.0** is supported since v6.0.2
+*   **Laravel 9.0** is supported since v6.0.1
+*   **Laravel 8.0** is supported since v6.0.0
+*   **Laravel 5.7, 5.8, 6.0, 7.0** is supported since v5
+*   **Laravel 5.5, 5.6** is supported since v4.3
+*   **Laravel 5.2, 5.3, 5.4** is supported since v4
 *   **Laravel 5.1** is supported in v3
 *   **Laravel 4** is supported in v2
 
-Although this project is completely free for use, I appreciate any support!
-
--   __[Donate via PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5TJUM7FYU5VR2)__
--   My Visa: 4276 0700 1073 4244
-
 __Contents:__
 
 - [Theory](#what-are-nested-sets)
@@ -384,6 +385,9 @@ position.
 Various constraints that can be applied to the query builder:
 
 -   __whereIsRoot()__ to get only root nodes;
+-   __hasParent()__ to get non-root nodes;
+-   __whereIsLeaf()__ to get only leaves;
+-   __hasChildren()__ to get non-leave nodes;
 -   __whereIsAfter($id)__ to get every node (not just siblings) that are after a node
     with specified id;
 -   __whereIsBefore($id)__ to get every node that is before a node with specified id.
@@ -571,17 +575,17 @@ protected function getScopeAttributes()
 }
 ```
 
-But now in order to execute some custom query, you need to provide attributes
+But now, in order to execute some custom query, you need to provide attributes
 that are used for scoping:
 
 ```php
 MenuItem::scoped([ 'menu_id' => 5 ])->withDepth()->get(); // OK
 MenuItem::descendantsOf($id)->get(); // WRONG: returns nodes from other scope
-MenuItem::scoped([ 'menu_id' => 5 ])->fixTree();
+MenuItem::scoped([ 'menu_id' => 5 ])->fixTree(); // OK
 ```
 
 When requesting nodes using model instance, scopes applied automatically based
-on the attributes of that model. See examples:
+on the attributes of that model:
 
 ```php
 $node = MenuItem::findOrFail($id);
@@ -595,12 +599,13 @@ To get scoped query builder using instance:
 $node->newScopedQuery();
 ```
 
-Note, that scoping is not required when retrieving model by primary key
-(since the key is unique):
+#### Scoping and eager loading
+
+Always use scoped query when eager loading:
 
 ```php
-$node = MenuItem::findOrFail($id); // OK
-$node = MenuItem::scoped([ 'menu_id' => 5 ])->findOrFail(); // OK, but redundant
+MenuItem::scoped([ 'menu_id' => 5])->with('descendants')->findOrFail($id); // OK
+MenuItem::with('descendants')->findOrFail($id); // WRONG
 ```
 
 Requirements
@@ -625,7 +630,21 @@ composer require kalnoy/nestedset
 
 #### The schema
 
-You can use a method to add needed columns with default names:
+For Laravel 5.5 and above users:
+
+```php
+Schema::create('table', function (Blueprint $table) {
+    ...
+    $table->nestedSet();
+});
+
+// To drop columns
+Schema::table('table', function (Blueprint $table) {
+    $table->dropNestedSet();
+});
+```
+
+For prior Laravel versions:
 
 ```php
 ...
diff --git a/composer.json b/composer.json
index efa2656..9f8d6c1 100644
--- a/composer.json
+++ b/composer.json
@@ -1,6 +1,6 @@
 {
     "name": "kalnoy/nestedset",
-    "description": "Nested Set Model for Laravel 4-5",
+    "description": "Nested Set Model for Laravel 5.7 and up",
     "keywords": ["laravel", "nested sets", "nsm", "database", "hierarchy"],
     "license": "MIT",
 
@@ -12,10 +12,10 @@
     ],
 
     "require": {
-        "php": ">=5.5.9",
-        "illuminate/support": "5.2 - 5.5",
-        "illuminate/database": "5.2 - 5.5",
-        "illuminate/events": "5.2 - 5.5"
+        "php": "^8.2",
+        "illuminate/support": "^11.0",
+        "illuminate/database": "^11.0",
+        "illuminate/events": "^11.0"
     },
 
     "autoload": {
@@ -24,15 +24,33 @@
         }
     },
 
+    "autoload-dev": {
+        "psr-4": {
+            "Kalnoy\\Nestedset\\Tests\\": "tests/"
+        }
+    },
+
     "require-dev": {
-        "phpunit/phpunit": "4.8.*"
+        "phpunit/phpunit": "10.*"
     },
 
     "minimum-stability": "dev",
+    "prefer-stable": true,
 
     "extra": {
         "branch-alias": {
-            "dev-master": "v4.2.x-dev"
+            "dev-master": "v5.0.x-dev"
+        },
+
+        "laravel": {
+            "providers": [
+                "Kalnoy\\Nestedset\\NestedSetServiceProvider"
+            ]
         }
+    },
+    "scripts": {
+        "test": [
+            "@php ./vendor/bin/phpunit"
+        ]
     }
 }
diff --git a/phpunit.php b/phpunit.php
index a9fa67a..7f72aff 100644
--- a/phpunit.php
+++ b/phpunit.php
@@ -8,4 +8,5 @@
 $capsule->bootEloquent();
 $capsule->setAsGlobal();
 
-include __DIR__.'/tests/models/Category.php';
\ No newline at end of file
+include __DIR__.'/tests/models/Category.php';
+include __DIR__.'/tests/models/MenuItem.php';
\ No newline at end of file
diff --git a/phpunit.xml b/phpunit.xml
index 80d7085..8021fb0 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -1,24 +1,21 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<phpunit backupGlobals="false"
-         backupStaticAttributes="false"
-         bootstrap="phpunit.php"
-         colors="true"
-         convertErrorsToExceptions="true"
-         convertNoticesToExceptions="true"
-         convertWarningsToExceptions="true"
-         processIsolation="false"
-         stopOnFailure="true"
-         syntaxCheck="false"
->
-    <testsuites>
-        <testsuite name="Package Test Suite">
-            <directory suffix=".php">./tests/</directory>
-        </testsuite>
-    </testsuites>
-
-    <filter>
-        <whitelist>
-            <directory>./src</directory>
-        </whitelist>
-    </filter>
-</phpunit>
\ No newline at end of file
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  backupGlobals="false"
+  bootstrap="phpunit.php"
+  colors="true"
+  processIsolation="false"
+  xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
+  cacheDirectory=".phpunit.cache"
+  backupStaticProperties="false"
+>
+  <testsuites>
+    <testsuite name="Package Test Suite">
+      <directory suffix=".php">./tests/</directory>
+    </testsuite>
+  </testsuites>
+  <source>
+    <include>
+      <directory>./src</directory>
+    </include>
+  </source>
+</phpunit>
diff --git a/src/AncestorsRelation.php b/src/AncestorsRelation.php
index 089e382..b59fba2 100644
--- a/src/AncestorsRelation.php
+++ b/src/AncestorsRelation.php
@@ -15,7 +15,8 @@ public function addConstraints()
     {
         if ( ! static::$constraints) return;
 
-        $this->query->whereAncestorOf($this->parent)->defaultOrder();
+        $this->query->whereAncestorOf($this->parent)
+            ->applyNestedSetScope();
     }
 
     /**
diff --git a/src/BaseRelation.php b/src/BaseRelation.php
index b09e031..7f82f29 100644
--- a/src/BaseRelation.php
+++ b/src/BaseRelation.php
@@ -111,28 +111,15 @@ public function initRelation(array $models, $relation)
         return $models;
     }
 
-    /**
-     * @param EloquentBuilder $query
-     * @param EloquentBuilder $parent
-     * @param array $columns
-     *
-     * @return mixed
-     */
-    public function getRelationQuery(
-        EloquentBuilder $query, EloquentBuilder $parent,
-        $columns = [ '*' ]
-    ) {
-        return $this->getRelationExistenceQuery($query, $parent, $columns);
-    }
-
     /**
      * Get a relationship join table hash.
      *
+     * @param  bool $incrementJoinCount
      * @return string
      */
-    public function getRelationCountHash()
+    public function getRelationCountHash($incrementJoinCount = true)
     {
-        return 'nested_set_'.self::$selfJoinCount++;
+        return 'nested_set_'.($incrementJoinCount ? static::$selfJoinCount++ : static::$selfJoinCount);
     }
 
     /**
@@ -154,10 +141,6 @@ public function getResults()
      */
     public function addEagerConstraints(array $models)
     {
-        $model = reset($models);
-
-        $this->query = $model->newScopedQuery();
-
         $this->query->whereNested(function (Builder $inner) use ($models) {
             // We will use this query in order to apply constraints to the
             // base query builder
@@ -207,4 +190,16 @@ protected function matchForModel(Model $model, EloquentCollection $results)
 
         return $result;
     }
-}
\ No newline at end of file
+
+    /**
+     * Get the plain foreign key.
+     *
+     * @return mixed
+     */
+    public function getForeignKeyName()
+    {
+        // Return a stub value for relation
+        // resolvers which need this function.
+        return NestedSet::PARENT_ID;
+    }
+}
diff --git a/src/DescendantsRelation.php b/src/DescendantsRelation.php
index 5240d3a..4c6457d 100644
--- a/src/DescendantsRelation.php
+++ b/src/DescendantsRelation.php
@@ -17,7 +17,8 @@ public function addConstraints()
     {
         if ( ! static::$constraints) return;
 
-        $this->query->whereDescendantOf($this->parent);
+        $this->query->whereDescendantOf($this->parent)
+        ->applyNestedSetScope();
     }
 
     /**
diff --git a/src/NestedSetServiceProvider.php b/src/NestedSetServiceProvider.php
new file mode 100644
index 0000000..b4516f7
--- /dev/null
+++ b/src/NestedSetServiceProvider.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace Kalnoy\Nestedset;
+
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\ServiceProvider;
+
+class NestedSetServiceProvider extends ServiceProvider
+{
+    public function register()
+    {
+        Blueprint::macro('nestedSet', function () {
+            NestedSet::columns($this);
+        });
+
+        Blueprint::macro('dropNestedSet', function () {
+            NestedSet::dropColumns($this);
+        });
+    }
+}
\ No newline at end of file
diff --git a/src/NodeTrait.php b/src/NodeTrait.php
index 167c001..c406ed8 100644
--- a/src/NodeTrait.php
+++ b/src/NodeTrait.php
@@ -7,6 +7,7 @@
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
 use Illuminate\Database\Eloquent\Relations\HasMany;
+use Illuminate\Support\Arr;
 use LogicException;
 
 trait NodeTrait
@@ -248,7 +249,7 @@ public function children()
      */
     public function descendants()
     {
-        return new DescendantsRelation($this->newScopedQuery(), $this);
+        return new DescendantsRelation($this->newQuery(), $this);
     }
 
     /**
@@ -337,7 +338,7 @@ public function prevNodes()
      */
     public function ancestors()
     {
-        return new AncestorsRelation($this->newScopedQuery(), $this);
+        return new AncestorsRelation($this->newQuery(), $this);
     }
 
     /**
@@ -724,7 +725,7 @@ protected function getScopeAttributes()
     /**
      * @param array $attributes
      *
-     * @return self
+     * @return QueryBuilder
      */
     public static function scoped(array $attributes)
     {
@@ -752,7 +753,7 @@ public function newCollection(array $models = array())
      */
     public static function create(array $attributes = [], self $parent = null)
     {
-        $children = array_pull($attributes, 'children');
+        $children = Arr::pull($attributes, 'children');
 
         $instance = new static($attributes);
 
@@ -1004,7 +1005,8 @@ public function getPrevSibling(array $columns = [ '*' ])
     public function isDescendantOf(self $other)
     {
         return $this->getLft() > $other->getLft() &&
-            $this->getLft() < $other->getRgt();
+            $this->getLft() < $other->getRgt() &&
+            $this->isSameScope($other);
     }
 
     /**
@@ -1200,6 +1202,24 @@ protected function assertSameScope(self $node)
         }
     }
 
+    /**
+     * @param self $node
+     */
+    protected function isSameScope(self $node): bool
+    {
+        if ( ! $scoped = $this->getScopeAttributes()) {
+            return true;
+        }
+
+        foreach ($scoped as $attr) {
+            if ($this->getAttribute($attr) != $node->getAttribute($attr)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
     /**
      * @param array|null $except
      *
diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php
index 56c702b..5be2e5b 100644
--- a/src/QueryBuilder.php
+++ b/src/QueryBuilder.php
@@ -86,9 +86,11 @@ public function whereIsRoot()
      */
     public function whereAncestorOf($id, $andSelf = false, $boolean = 'and')
     {
-        $keyName = $this->model->getKeyName();
+        $keyName = $this->model->getTable() . '.' . $this->model->getKeyName();
+        $model = null;
 
         if (NestedSet::isNode($id)) {
+            $model = $id;
             $value = '?';
 
             $this->query->addBinding($id->getRgt());
@@ -100,7 +102,7 @@ public function whereAncestorOf($id, $andSelf = false, $boolean = 'and')
                 ->toBase()
                 ->select("_.".$this->model->getRgtName())
                 ->from($this->model->getTable().' as _')
-                ->where($keyName, '=', $id)
+                ->where($this->model->getKeyName(), '=', $id)
                 ->limit(1);
 
             $this->query->mergeBindings($valueQuery);
@@ -108,17 +110,22 @@ public function whereAncestorOf($id, $andSelf = false, $boolean = 'and')
             $value = '('.$valueQuery->toSql().')';
         }
 
-        $this->query->whereNested(function ($inner) use ($value, $andSelf, $id) {
+        $this->query->whereNested(function ($inner) use ($model, $value, $andSelf, $id, $keyName) {
             list($lft, $rgt) = $this->wrappedColumns();
+            $wrappedTable = $this->query->getGrammar()->wrapTable($this->model->getTable());
 
-            $inner->whereRaw("{$value} between {$lft} and {$rgt}");
+            $inner->whereRaw("{$value} between {$wrappedTable}.{$lft} and {$wrappedTable}.{$rgt}");
 
             if ( ! $andSelf) {
-                $inner->where($this->model->getKeyName(), '<>', $id);
+                $inner->where($keyName, '<>', $id);
+            }
+            if ($model !== null) {
+                // we apply scope only when Node was passed as $id.
+                // In other cases, according to docs, query should be scoped() before calling this method
+                $model->applyNestedSetScope($inner);
             }
         }, $boolean);
 
-
         return $this;
     }
 
@@ -177,12 +184,13 @@ public function ancestorsAndSelf($id, array $columns = [ '*' ])
      * @param array $values
      * @param string $boolean
      * @param bool $not
+     * @param Query $query
      *
      * @return $this
      */
-    public function whereNodeBetween($values, $boolean = 'and', $not = false)
+    public function whereNodeBetween($values, $boolean = 'and', $not = false, $query = null)
     {
-        $this->query->whereBetween($this->model->getLftName(), $values, $boolean, $not);
+        ($query ?? $this->query)->whereBetween($this->model->getTable() . '.' . $this->model->getLftName(), $values, $boolean, $not);
 
         return $this;
     }
@@ -216,19 +224,26 @@ public function orWhereNodeBetween($values)
     public function whereDescendantOf($id, $boolean = 'and', $not = false,
                                       $andSelf = false
     ) {
-        if (NestedSet::isNode($id)) {
-            $data = $id->getBounds();
-        } else {
-            $data = $this->model->newNestedSetQuery()
-                                ->getPlainNodeData($id, true);
-        }
+        $this->query->whereNested(function (Query $inner) use ($id, $andSelf, $not) {
+            if (NestedSet::isNode($id)) {
+                $id->applyNestedSetScope($inner);
+                $data = $id->getBounds();
+            } else {
+                // we apply scope only when Node was passed as $id.
+                // In other cases, according to docs, query should be scoped() before calling this method
+                $data = $this->model->newNestedSetQuery()
+                    ->getPlainNodeData($id, true);
+            }
 
-        // Don't include the node
-        if ( ! $andSelf) {
-            ++$data[0];
-        }
+            // Don't include the node
+            if (!$andSelf) {
+                ++$data[0];
+            }
 
-        return $this->whereNodeBetween($data, $boolean, $not);
+            return $this->whereNodeBetween($data, 'and', $not, $inner);
+        }, $boolean);
+
+        return $this;
     }
 
     /**
@@ -715,6 +730,7 @@ protected function getOdnessQuery()
     protected function getDuplicatesQuery()
     {
         $table = $this->wrappedTable();
+        $keyName = $this->wrappedKey();
 
         $firstAlias = 'c1';
         $secondAlias = 'c2';
@@ -727,7 +743,7 @@ protected function getDuplicatesQuery()
             ->newNestedSetQuery($firstAlias)
             ->toBase()
             ->from($this->query->raw("{$table} as {$waFirst}, {$table} {$waSecond}"))
-            ->whereRaw("{$waFirst}.{$pk} < {$waSecond}.{$pk}")
+            ->whereRaw("{$waFirst}.{$keyName} < {$waSecond}.{$keyName}")
             ->whereNested(function (BaseQueryBuilder $inner) use ($waFirst, $waSecond) {
                 list($lft, $rgt) = $this->wrappedColumns();
 
diff --git a/tests/.gitkeep b/tests/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/tests/NodeTest.php b/tests/NodeTest.php
index 3f7bad0..16d6d9e 100644
--- a/tests/NodeTest.php
+++ b/tests/NodeTest.php
@@ -2,10 +2,11 @@
 
 use Illuminate\Database\Capsule\Manager as Capsule;
 use Kalnoy\Nestedset\NestedSet;
+use Kalnoy\Nestedset\Tests\Models\Category;
 
-class NodeTest extends PHPUnit_Framework_TestCase
+class NodeTest extends PHPUnit\Framework\TestCase
 {
-    public static function setUpBeforeClass()
+    public static function setUpBeforeClass(): void
     {
         $schema = Capsule::schema();
 
@@ -23,7 +24,7 @@ public static function setUpBeforeClass()
         Capsule::enableQueryLog();
     }
 
-    public function setUp()
+    public function setUp(): void
     {
         $data = include __DIR__.'/data/categories.php';
 
@@ -36,7 +37,7 @@ public function setUp()
         date_default_timezone_set('America/Denver');
     }
 
-    public function tearDown()
+    public function tearDown(): void
     {
         Capsule::table('categories')->truncate();
     }
@@ -104,12 +105,7 @@ public function assertNodeReceivesValidValues($node)
         );
     }
 
-    /**
-     * @param $name
-     *
-     * @return \Category
-     */
-    public function findCategory($name, $withTrashed = false)
+    public function findCategory(string $name, bool $withTrashed = false): Category
     {
         $q = new Category;
 
@@ -221,32 +217,29 @@ public function testCategoryMovesUp()
         $this->assertNodeReceivesValidValues($node);
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testFailsToInsertIntoChild()
     {
+        $this->expectException(Exception::class);
+
         $node = $this->findCategory('notebooks');
         $target = $node->children()->first();
 
         $node->afterNode($target)->save();
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testFailsToAppendIntoItself()
     {
+        $this->expectException(Exception::class);
+
         $node = $this->findCategory('notebooks');
 
         $node->appendToNode($node)->save();
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testFailsToPrependIntoItself()
     {
+        $this->expectException(Exception::class);
+
         $node = $this->findCategory('notebooks');
 
         $node->prependTo($node)->save();
@@ -338,11 +331,10 @@ public function testParentIdAttributeAccessorAppendsNode()
         $this->assertTrue($node->isRoot());
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testFailsToSaveNodeUntilNotInserted()
     {
+        $this->expectException(Exception::class);
+
         $node = new Category;
         $node->save();
     }
@@ -405,11 +397,10 @@ public function testSoftDeletedNodeisDeletedWhenParentIsDeleted()
         $this->assertNull($this->findCategory('sony'));
     }
 
-    /**
-     * @expectedException Exception
-     */
     public function testFailsToSaveNodeUntilParentIsSaved()
     {
+        $this->expectException(Exception::class);
+
         $node = new Category(array('title' => 'Node'));
         $parent = new Category(array('title' => 'Parent'));
 
@@ -641,11 +632,10 @@ public function testDescendantsOfNonExistingNode()
         $this->assertTrue($node->getDescendants()->isEmpty());
     }
 
-    /**
-     * @expectedException \Illuminate\Database\Eloquent\ModelNotFoundException
-     */
     public function testWhereDescendantsOf()
     {
+        $this->expectException(\Illuminate\Database\Eloquent\ModelNotFoundException::class);
+
         Category::whereDescendantOf(124)->get();
     }
 
@@ -827,8 +817,6 @@ public function testRebuildSubtree()
             [ 'id' => '8' ],
         ]);
 
-        echo PHP_EOL.$fixed.PHP_EOL;
-
         $this->assertTrue($fixed > 0);
         $this->assertTreeNotBroken();
 
@@ -854,11 +842,10 @@ public function testRebuildTreeWithDeletion()
         $this->assertTrue($nodes->count() > 1);
     }
 
-    /**
-     * @expectedException \Illuminate\Database\Eloquent\ModelNotFoundException
-     */
     public function testRebuildFailsWithInvalidPK()
     {
+        $this->expectException(\Illuminate\Database\Eloquent\ModelNotFoundException::class);
+
         Category::rebuildTree([ [ 'id' => 24 ] ]);
     }
 
@@ -872,7 +859,9 @@ public function testFlatTree()
         $this->assertEquals('galaxy', $tree[3]->name);
     }
 
-    public function testSeveralNodesModelWork()
+    // Commented, cause there is no assertion here and otherwise the test is marked as risky in PHPUnit 7.
+    // What's the purpose of this method? @todo: remove/update?
+    /*public function testSeveralNodesModelWork()
     {
         $category = new Category;
 
@@ -885,7 +874,7 @@ public function testSeveralNodesModelWork()
         $duplicate->name = 'test';
 
         $duplicate->saveAsRoot();
-    }
+    }*/
 
     public function testWhereIsLeaf()
     {
diff --git a/tests/ScopedNodeTest.php b/tests/ScopedNodeTest.php
index 0584ca7..aed1fe1 100644
--- a/tests/ScopedNodeTest.php
+++ b/tests/ScopedNodeTest.php
@@ -2,10 +2,11 @@
 
 use Illuminate\Database\Capsule\Manager as Capsule;
 use Kalnoy\Nestedset\NestedSet;
+use Kalnoy\Nestedset\Tests\Models\MenuItem;
 
-class ScopedNodeTest extends PHPUnit_Framework_TestCase
+class ScopedNodeTest extends PHPUnit\Framework\TestCase
 {
-    public static function setUpBeforeClass()
+    public static function setUpBeforeClass(): void
     {
         $schema = Capsule::schema();
 
@@ -23,7 +24,7 @@ public static function setUpBeforeClass()
         Capsule::enableQueryLog();
     }
 
-    public function setUp()
+    public function setUp(): void
     {
         $data = include __DIR__.'/data/menu_items.php';
 
@@ -36,7 +37,7 @@ public function setUp()
         date_default_timezone_set('America/Denver');
     }
 
-    public function tearDown()
+    public function tearDown(): void
     {
         Capsule::table('menu_items')->truncate();
     }
@@ -98,6 +99,13 @@ public function testDescendants()
 
         $this->assertEquals(1, $result->count());
         $this->assertEquals(5, $result->first()->getKey());
+
+        $node = MenuItem::scoped([ 'menu_id' => 1 ])->with('descendants')->find(2);
+
+        $result = $node->descendants;
+
+        $this->assertEquals(1, $result->count());
+        $this->assertEquals(5, $result->first()->getKey());
     }
 
     public function testAncestors()
@@ -109,7 +117,7 @@ public function testAncestors()
         $this->assertEquals(1, $result->count());
         $this->assertEquals(2, $result->first()->getKey());
 
-        $node = MenuItem::with('ancestors')->find(5);
+        $node = MenuItem::scoped([ 'menu_id' => 1 ])->with('ancestors')->find(5);
 
         $result = $node->ancestors;
 
@@ -152,11 +160,10 @@ public function testInsertion()
         $this->assertOtherScopeNotAffected();
     }
 
-    /**
-     * @expectedException \Illuminate\Database\Eloquent\ModelNotFoundException
-     */
     public function testInsertionToParentFromOtherScope()
     {
+        $this->expectException(\Illuminate\Database\Eloquent\ModelNotFoundException::class);
+
         $node = MenuItem::create([ 'menu_id' => 2, 'parent_id' => 5 ]);
     }
 
@@ -186,31 +193,47 @@ protected function assertOtherScopeNotAffected()
         $this->assertEquals(1, $node->getLft());
     }
 
-    public function testRebuildsTree()
+    // Commented, cause there is no assertion here and otherwise the test is marked as risky in PHPUnit 7.
+    // What's the purpose of this method? @todo: remove/update?
+    /*public function testRebuildsTree()
     {
         $data = [];
         MenuItem::scoped([ 'menu_id' => 2 ])->rebuildTree($data);
-    }
+    }*/
 
-    /**
-     * @expectedException LogicException
-     */
     public function testAppendingToAnotherScopeFails()
     {
+        $this->expectException(LogicException::class);
+
         $a = MenuItem::find(1);
         $b = MenuItem::find(3);
 
         $a->appendToNode($b)->save();
     }
 
-    /**
-     * @expectedException LogicException
-     */
     public function testInsertingBeforeAnotherScopeFails()
     {
+        $this->expectException(LogicException::class);
+
         $a = MenuItem::find(1);
         $b = MenuItem::find(3);
 
         $a->insertAfterNode($b);
     }
+
+    public function testEagerLoadingAncestorsWithScope()
+    {
+        $filteredNodes = MenuItem::where('title', 'menu item 3')->with(['ancestors'])->get();
+
+        $this->assertEquals(2, $filteredNodes->find(5)->ancestors[0]->id);
+        $this->assertEquals(4, $filteredNodes->find(6)->ancestors[0]->id);
+    }
+
+    public function testEagerLoadingDescendantsWithScope()
+    {
+        $filteredNodes = MenuItem::where('title', 'menu item 2')->with(['descendants'])->get();
+
+        $this->assertEquals(5, $filteredNodes->find(2)->descendants[0]->id);
+        $this->assertEquals(6, $filteredNodes->find(4)->descendants[0]->id);
+    }
 }
\ No newline at end of file
diff --git a/tests/data/categories.php b/tests/data/categories.php
index 1f5b8ab..cd16d40 100644
--- a/tests/data/categories.php
+++ b/tests/data/categories.php
@@ -1,15 +1,15 @@
 <?php
 
-return array(
-    array('id' => 1, 'name' => 'store', '_lft' => 1, '_rgt' => 20, 'parent_id' => null),
-        array('id' => 2, 'name' => 'notebooks', '_lft' => 2, '_rgt' => 7, 'parent_id' => 1),
-            array('id' => 3, 'name' => 'apple', '_lft' => 3, '_rgt' => 4, 'parent_id' => 2),
-            array('id' => 4, 'name' => 'lenovo', '_lft' => 5, '_rgt' => 6, 'parent_id' => 2),
-        array('id' => 5, 'name' => 'mobile', '_lft' => 8, '_rgt' => 19, 'parent_id' => 1),
-            array('id' => 6, 'name' => 'nokia', '_lft' => 9, '_rgt' => 10, 'parent_id' => 5),
-            array('id' => 7, 'name' => 'samsung', '_lft' => 11, '_rgt' => 14, 'parent_id' => 5),
-                array('id' => 8, 'name' => 'galaxy', '_lft' => 12, '_rgt' => 13, 'parent_id' => 7),
-            array('id' => 9, 'name' => 'sony', '_lft' => 15, '_rgt' => 16, 'parent_id' => 5),
-            array('id' => 10, 'name' => 'lenovo', '_lft' => 17, '_rgt' => 18, 'parent_id' => 5),
-    array('id' => 11, 'name' => 'store_2', '_lft' => 21, '_rgt' => 22, 'parent_id' => null),
-);
\ No newline at end of file
+return [
+    ['id' => 1, 'name' => 'store', '_lft' => 1, '_rgt' => 20, 'parent_id' => null],
+        ['id' => 2, 'name' => 'notebooks', '_lft' => 2, '_rgt' => 7, 'parent_id' => 1],
+            ['id' => 3, 'name' => 'apple', '_lft' => 3, '_rgt' => 4, 'parent_id' => 2],
+            ['id' => 4, 'name' => 'lenovo', '_lft' => 5, '_rgt' => 6, 'parent_id' => 2],
+        ['id' => 5, 'name' => 'mobile', '_lft' => 8, '_rgt' => 19, 'parent_id' => 1],
+            ['id' => 6, 'name' => 'nokia', '_lft' => 9, '_rgt' => 10, 'parent_id' => 5],
+            ['id' => 7, 'name' => 'samsung', '_lft' => 11, '_rgt' => 14, 'parent_id' => 5],
+                ['id' => 8, 'name' => 'galaxy', '_lft' => 12, '_rgt' => 13, 'parent_id' => 7],
+            ['id' => 9, 'name' => 'sony', '_lft' => 15, '_rgt' => 16, 'parent_id' => 5],
+            ['id' => 10, 'name' => 'lenovo', '_lft' => 17, '_rgt' => 18, 'parent_id' => 5],
+    ['id' => 11, 'name' => 'store_2', '_lft' => 21, '_rgt' => 22, 'parent_id' => null],
+];
\ No newline at end of file
diff --git a/tests/data/menu_items.php b/tests/data/menu_items.php
index 5490f7d..fba6acb 100644
--- a/tests/data/menu_items.php
+++ b/tests/data/menu_items.php
@@ -1,8 +1,10 @@
-<?php return [
-    [ 'id' => 1, 'menu_id' => 1, '_lft' => 1, '_rgt' => 2, 'parent_id' => null, 'title' => 'menu item 1' ],
-    [ 'id' => 2, 'menu_id' => 1, '_lft' => 3, '_rgt' => 6, 'parent_id' => null, 'title' => 'menu item 2' ],
-        [ 'id' => 5, 'menu_id' => 1, '_lft' => 4, '_rgt' => 5, 'parent_id' => 2, 'title' => 'menu item 3' ],
-    [ 'id' => 3, 'menu_id' => 2, '_lft' => 1, '_rgt' => 2, 'parent_id' => null, 'title' => 'menu item 1' ],
-    [ 'id' => 4, 'menu_id' => 2, '_lft' => 3, '_rgt' => 6, 'parent_id' => null, 'title' => 'menu item 2' ],
-        [ 'id' => 6, 'menu_id' => 2, '_lft' => 4, '_rgt' => 5, 'parent_id' => 4, 'title' => 'menu item 3' ],
+<?php
+
+return [
+    ['id' => 1, 'menu_id' => 1, '_lft' => 1, '_rgt' => 2, 'parent_id' => null, 'title' => 'menu item 1' ],
+    ['id' => 2, 'menu_id' => 1, '_lft' => 3, '_rgt' => 6, 'parent_id' => null, 'title' => 'menu item 2' ],
+        ['id' => 5, 'menu_id' => 1, '_lft' => 4, '_rgt' => 5, 'parent_id' => 2, 'title' => 'menu item 3' ],
+    ['id' => 3, 'menu_id' => 2, '_lft' => 1, '_rgt' => 2, 'parent_id' => null, 'title' => 'menu item 1' ],
+    ['id' => 4, 'menu_id' => 2, '_lft' => 3, '_rgt' => 6, 'parent_id' => null, 'title' => 'menu item 2' ],
+        ['id' => 6, 'menu_id' => 2, '_lft' => 4, '_rgt' => 5, 'parent_id' => 4, 'title' => 'menu item 3' ],
 ];
\ No newline at end of file
diff --git a/tests/models/Category.php b/tests/models/Category.php
index bcce8e9..0c35daa 100644
--- a/tests/models/Category.php
+++ b/tests/models/Category.php
@@ -1,12 +1,17 @@
 <?php
 
+namespace Kalnoy\Nestedset\Tests\Models;
+
 use \Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
+use Kalnoy\Nestedset\NodeTrait;
 
 class Category extends Model {
 
-    use \Illuminate\Database\Eloquent\SoftDeletes, \Kalnoy\Nestedset\NodeTrait;
+    use SoftDeletes;
+    use NodeTrait;
 
-    protected $fillable = array('name', 'parent_id');
+    protected $fillable = ['name', 'parent_id'];
 
     public $timestamps = false;
 
diff --git a/tests/models/DuplicateCategory.php b/tests/models/DuplicateCategory.php
index a6f619a..f7f0e31 100644
--- a/tests/models/DuplicateCategory.php
+++ b/tests/models/DuplicateCategory.php
@@ -1,12 +1,16 @@
 <?php
 
+namespace Kalnoy\Nestedset\Tests\Models;
+
+use Kalnoy\Nestedset\NodeTrait;
+
 class DuplicateCategory extends \Illuminate\Database\Eloquent\Model
 {
-    use \Kalnoy\Nestedset\NodeTrait;
+    use NodeTrait;
 
     protected $table = 'categories';
 
-    protected $fillable = [ 'name' ];
+    protected $fillable = ['name'];
 
     public $timestamps = false;
 }
\ No newline at end of file
diff --git a/tests/models/MenuItem.php b/tests/models/MenuItem.php
index 2e10a55..27c87ac 100644
--- a/tests/models/MenuItem.php
+++ b/tests/models/MenuItem.php
@@ -1,13 +1,16 @@
 <?php
 
+namespace Kalnoy\Nestedset\Tests\Models;
+
+use Kalnoy\Nestedset\NodeTrait;
 
 class MenuItem extends \Illuminate\Database\Eloquent\Model
 {
-    use \Kalnoy\Nestedset\NodeTrait;
+    use NodeTrait;
 
     public $timestamps = false;
 
-    protected $fillable = ['menu_id','parent_id'];
+    protected $fillable = ['menu_id', 'parent_id'];
 
     public static function resetActionsPerformed()
     {